-1

I would like to find out how to assign and execute an operation with the value variable.

Suppose that I get these files as a result of ls -A *.pdf | grep -v '^d':

firstOne.pdf
ordenSiq.pdf

Now I'm trying to execute any operation later of assignment, an example:

% ls -lAh ordenSiq.pdf
-rw-r--r--@ 1 joseluisbz  staff    47K Jun 29 15:35 ordenSiq.pdf

Here my attempt (but is not working!)

awk -v thelast="$(ls -A *.pdf | grep -v '^d' | tail -n 1 | awk '{print}')" 'BEGIN {ls -lAh thelast;}'

EDIT

  1. Obtaining The Last File With Extension!

% thelast=$(ls -A *.pdf | grep -v '^d' | tail -n 1 | awk '{print}'); awk -v result=$thelast 'BEGIN{print result}' Otutput: ordenSiq.pdf

  1. Extracting Only The Name (split)

% thelast=$(ls -A *.pdf | grep -v '^d' | tail -n 1 | awk '{print}'); thename=$(echo ${thelast} | awk '{split($0,a,"."); print a[1]}'); awk -v result="$thename" 'BEGIN{print result}' Output:ordenSiq

  1. ALL Extensions For name (concatenation)

% thelast=$(ls -A *.pdf | grep -v '^d' | tail -n 1 | awk '{print}'); thename=$(echo ${thelast} | awk '{split($0,a,"."); print a[1]}'); allexts=$(echo ${thename}'.*'); awk -v result="$allnames" 'BEGIN{print result}' Output:ordenSiq.*

or

thelast=$(ls -A *.pdf | grep -v '^d' | tail -n 1 | awk '{print}'); thename=$(echo ${thelast} | awk '{split($0,a,"."); print a[1]}'); awk -v allexts=${thename}".*" 'BEGIN{print allexts}'

  1. Execution of command with variable

I would like to obtain something like:

% ls -lAh ordenSiq.*
-rw-r--r--  1 joseluisbz  staff     0B Jul 15 12:34 ordenSiq.abc
-rw-r--r--  1 joseluisbz  staff     0B Jul 15 12:34 ordenSiq.def
-rw-r--r--@ 1 joseluisbz  staff    47K Jun 29 15:35 ordenSiq.pdf
% 

ERROR:

% thelast=$(ls -A *.pdf | grep -v '^d' | tail -n 1 | awk '{print}'); thename=$(echo ${thelast} | awk '{split($0,a,"."); print a[1]}'); awk -v allexts=${thename}".*" 'BEGIN{system(ls -lAh allexts)}' Output:

sh: 0ordenSiq.*: command not found

And with

thelast=$(ls -A *.pdf | grep -v '^d' | tail -n 1 | awk '{print}'); thename=$(echo ${thelast} | awk '{split($0,a,"."); print a[1]}'); awk -v allexts=${thename}".*" 'BEGIN{system(ls -lAh $allexts)}' Output:

awk: illegal field $(ordenSiq.*), name "allexts"
 source line number 1

Some Working example:

% root1="/webroot"; echo | awk -v r=$root1 '{ print "shell variable $root1 value is " r}' Output:

shell variable $root1 value is /webroot

Statically Works!

% ls -lAh ordenSiq.*                                                                                                                                                                    
-rw-r--r--  1 joseluisbz  staff     0B Jul 15 12:34 ordenSiq.abc
-rw-r--r--  1 joseluisbz  staff     0B Jul 15 12:34 ordenSiq.def
-rw-r--r--@ 1 joseluisbz  staff    47K Jun 29 15:35 ordenSiq.pdf
%

And the variable's value is correct!

% thelast=$(ls -A *.pdf | grep -v '^d' | tail -n 1 | awk '{print}'); thename=$(echo ${thelast} | awk '{split($0,a,"."); print a[1]}'); allexts=$(echo ${thename}'.*'); echo ${allexts} Output:

ordenSiq.*

But doing this, do not work;

% thelast=$(ls -A *.pdf | grep -v '^d' | tail -n 1 | awk '{print}'); thename=$(echo ${thelast} | awk '{split($0,a,"."); print a[1]}'); allexts=$(echo ${thename}'.*'); ls -lAh $allexts Output:

ls: ordenSiq.*: No such file or directory

QUESTION:

What is wrong in my steps in order to perform the final operation with variables (with and without AWK)?

joseluisbz
  • 1,491
  • 1
  • 36
  • 58
  • 1
    It's hard to know how to help as your starting point for each command line ([parsing the output of `ls`](https://mywiki.wooledge.org/ParsingLs)) is wrong and you're asking how to implement something based on it when you shouldn't do so. It's really an [XY question](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). Can you fix it to tell and show us WHAT you're trying to do in addition to what you currently have which is HOW you're trying to do whatever it is? – Ed Morton Jul 15 '22 at 12:28
  • @ed-morton I edited my question in order to do it simpler... Thanks in advance. – joseluisbz Jul 15 '22 at 18:54
  • OK, best I can tell what I have in my answer does everything you want. If not, please state what else you need. – Ed Morton Jul 15 '22 at 19:32
  • My result... `% allexts=ordenSiq.*; echo ${allexts}; ls -lh "${allexts[@]}" ordenSiq.* ls: ordenSiq.*: No such file or directory` I working in *macOS* maybe is a problem of my OS. – joseluisbz Jul 15 '22 at 19:46
  • The first 2 commands are not present in the code in my answer and would result in errors from the 3rd command where you're trying to access a scalar variable as if it were an array and the quoted contents of that variable is a literal string that is not the name of any file. This has nothing to do with macOS, it's all shell stuff. Having said that - I'm assuming bash in my answer so make sure you're using that **if** you run into errors. – Ed Morton Jul 15 '22 at 19:53
  • Please just try exactly the code in my answer (without modifying it) and let us know if that works for you or not. – Ed Morton Jul 15 '22 at 19:54

2 Answers2

0
{ls -lAh thelast;}

This is not correct way of using shell command in GNU AWK, you should prepare string with command and then use system function, so for example if you want to sleep for 5 seconds at beginning you might do

awk 'BEGIN{system("sleep 5")}'

Keep in mind that system function returns exit status code (see linked documentation for further discussion), not output of command.

Daweo
  • 31,313
  • 3
  • 12
  • 25
  • Thanks a lot. But I need to use a chained variables too and I don't know ho to apply your help. Calculate a variable, calculate a second variable...and use them as the examples in my questions. Thanks in advance again! – joseluisbz Jul 15 '22 at 11:52
  • I was trying the first part with: `awk -v thelast="$(ls -A *.pdf | grep -v '^d' | tail -n 1 | awk '{print}')" 'BEGIN {system(ls -lAh thelast);}'` and I try with: `awk 'BEGIN {thelast="$(ls -A *.pdf | grep -v '^d' | tail -n 1 | awk '{print}')"} {system(ls -al thelast);}'` Unfortunately both don't work! – joseluisbz Jul 15 '22 at 12:23
0

I think this is what you're trying to do:

thelast=$(find . -type f -name '*.pdf' -printf '%T@\t%p\n' | sort -n | cut -f2- | tail -n 1)
thename="${thelast%.pdf}"
allexts=( "$thename".* )
ls -lh "${allexts[@]}"

As for what's wrong with your original code:

% thelast=$(ls -A *.pdf | grep -v '^d' | tail -n 1 | awk '{print}'); thename=$(echo ${thelast} | awk '{split($0,a,"."); print a[1]}'); allexts=$(echo ${thename}'.*'); ls -lAh $allexts
  1. It's trying to parse the output of ls, see https://mywiki.wooledge.org/ParsingLs
  2. It's removing the names of files that start with d for unknown reasons.
  3. It's not listing the files in time order
  4. It's using awk '{print}' which does nothing but copy the input to the output.
  5. It's got unquoted variables (copy/paste your code into http://shellcheck.net and it'll tell you about the basic issues)
  6. echo ${thename}'.*' is leaving the part that needs to be double-quoted unquoted and then single-quoting the part that needs to be unquoted.
  7. Using split() in awk as you are would corrupt file names that contain multiple .s.
  8. There may be other issues that aren't as obvious, idk.
Ed Morton
  • 188,023
  • 17
  • 78
  • 185
  • I need to include the *split*, *concatenate*, *variable assignation of other variables* in order to perform other complex functions/operations. – joseluisbz Jul 15 '22 at 18:51