awk command not outputting(awk: error cant open source file) - linux

Hey guys I'm trying to delete everything after the last / in a string (the parameter). I'm getting some issues that I can't quite figure out.. Sorry in advance for any stupid mistake I've made
myvar1 = $(echo $1 | awk -f "/" '(print $NF)')
Sample input:
./root/desktop/test
Sample output:
test

You should be using -F, not -f but there's other issues too. Change the whole line to:
myvar1=$(echo "$1" | awk -F'/' '{print $NF}')
IF you really want to use echo, awk and a pipe for this instead of just a bash builtin.
Also, the above selects whats after the last '/' not deletes everything after it so its not clear what you really want. Post some sample input and expected output if you can't figure it out from this:
$ x="a/b/c/d"; echo "${x##*/}"
d
$ x="a/b/c/d"; echo "${x%/*}"
a/b/c

Just another solution:
$ x=`basename /a/b/file`; echo $x
file
$ x=`dirname /a/b/file` ; echo $x
/a/b

Related

Bash - Piping output of command into while loop

I'm writing a Bash script where I need to look through the output of a command and do certain actions based on that output. For clarity, this command will output a few million lines of text and it may take roughly an hour or so to do so.
Currently, I'm executing the command and piping it into a while loop that reads a line at a time then looks for certain criteria. If that criterion exists, then update a .dat file and reprint the screen. Below is a snippet of the script.
eval "$command"| while read line ; do
if grep -Fq "Specific :: Criterion"; then
#pull the sixth word from the line which will have the data I need
temp=$(echo "$line" | awk '{ printf $6 }')
#sanity check the data
echo "\$line = $line"
echo "\$temp = $temp"
#then push $temp through a case statement that does what I need it to do.
fi
done
So here's the problem, the sanity check on the data is showing weird results. It is printing lines that don't contain the grep criteria.
To make sure that my grep statement is working properly, I grep the log file that contains a record of the text that is output by the command and it outputs only the lines that contain the specified criteria.
I'm still fairly new to Bash so I'm not sure what's going on. Could it be that the command is force feeding the while loop a new $line before it can process the $line that met the grep criteria?
Any ideas would be much appreciated!
How does grep know what line looks like?
if ( printf '%s\n' "$line" | grep -Fq "Specific :: Criterion"); then
But I cant help feel like you are overcomplicating a lot.
function process() {
echo "I can do anything I want"
echo " per element $1"
echo " that I want here"
}
export -f process
$command | grep -F "Specific :: Criterion" | awk '{print $6}' | xargs -I % -n 1 bash -c "process %";
Run the command, filter only matching lines, and pull the sixth element. Then if you need to run an arbitrary code on it, send it to a function (you export to make it visible in subprocesses) via xargs.
What are you applying the grep on ?
Modify
if grep -Fq "Specific :: Criterion"; then
as below
if ( echo $line | grep -Fq "Specific :: Criterion" ); then

Ubuntu bash script grepping and cutting on first column

I am trying to implement a bash script that will take the piped input and cut the first column and return a total. The difference is that the cut is not from a file, but from the piped input. For example:
#!/bin/bash
total=$(cut -f1 $1 | numsum)
echo $total
Basically, in my scenario the first column will always be from the passed input.
Example usuage is:
./script.sh "cat data.txt | grep -i status | grep something"
data.txt contains:
1 status
2 something
This will produce something like:
2
How can this be achieved? I have noticed the cut only works for files only. I cannot see any examples on Google.
I have managed to fix the issue myself. The code is:
#!/bin/bash
total=$(eval $1 | awk '{sum+=$1} END {print sum}')
echo $total

bash: grep in loop does not grep

I have (probably a obvious/stupid) problem:
I want to loop over a list of paths, cut them and use the strings to grep in log files.
While every step works fine on its own and 'processed manually' results in hits - grep does not find anything when in the loop?
for FILE in `awk -F "/" '{print $13}' /tmp/files_not_visible.uniq`; do
echo -e "\n\n$FILE\n";
grep "$FILE" /var/log/PATH/FILENAME-2015.12.*;
done
I also tried to do a while loop as reverse exercise, but fails with the same non-result
while read FILE; do
echo $FILE;
echo $FILE | awk -F "/" '{print $13}' | grep -f - /var/log/PATH/FILENAME-2015.12.* ;
done < /tmp/files_not_visible.uniq/tmp/files_not_visible.uniq
So, I guess there is some systematic issue, how I handle the search string with grep?
Found it: the list of files contained invisible characters as the last character of the line! Probably the user, who send me the list of files, created it on some other OS! And I only copied -of course- the visible characters when testing by hand!
Fixed the loop by cutting the last character of a line with
> sed -e 's/.$//'

How can I cat output of a system("pwd") with text in awk?

Please bear with me as I'm very new to shell scripting and awk. I've been trying to create a playlist to play some of my music in Mplayer, but it only works if the full path to each file is specified. I've been trying to set up a little shell script to insert the output of $pwd before each filename and write it to a playlist, like so:
ls | awk '{system("pwd") | getline x; grep -v 0; gsub("\n",""); print x"/"$1}' > playlist.txt
(the grep is to get rid of the "0" status output from system("pwd")). However, there is a newline in x, so I get the output
/home/(directory)
/Song_1.mp3
/home/(directory)
/Song_2.mp3
and what I want is
/home/(directory)/Song_1.mp3
/home/(directory)/Song_2.mp3
As others have answered, there are other ways to get the fully-qualified paths requested in the OP.
For those who are using Awk for other purposes and require the working directory, Awk has access to environment variables through the ENVIRON array. You can access it via ENVIRON["PWD"].
The directory is fully qualified, so the requested /home/(directory)/filename.mp3 may not quite work as expected. Even so, a one-liner that should work for OP's purpose:
ls -1 | awk '{ print(ENVIRON["PWD"] "/" $0); }' > playlist.txt
You can use printf like this:
printf "%s\n" "$PWD"/*
OR else your awk:
printf "%s\n" * | awk 'BEGIN{"pwd"|getline d} {print d "/" $0}'
Not using awk or anything, but I think this does what you want?
find -printf "\"$PWD/%f\"\n"
Are you perhaps trying to do this?
ls -1 ${PWD}/*.mp3
or
find "${PWD}" -maxdepth 1 -name "*.mp3" -print
or
for f in ${PWD}/*.mp3
do
echo "${f}"
done
You could also do
find $(pwd) -maxdepth 1

How to get extension of a file in shell script

I am trying to get file extension for a file in shell script. But without any luck.
The command I am using is
file_ext=${filename##*.}
and
file_ext = $filename |awk -F . '{if (NF>1) {print $NF}}'
But both of the commands failed to put value in variable file_ext. But when i try
echo $filename |awk -F . '{if (NF>1) {print $NF}}'
It gives me the desired result. I am new to shell script. Please describe the situation what is happening. And also how should I do it?
Thanks.
to get file extension, just use the shell
$ filename="myfile.ext"
$ echo ${filename##*.}
ext
$ file_ext=${filename##*.} #put to variable
$ echo ${file_ext}
ext
Spaces hurt.
Anyway you should do:
file_ext=$(echo $filename | awk -F . '{if (NF>1) {print $NF}}')
[Edit] Better suggestion by Martin:
file_ext=$(printf '%s' "$filename" | awk -F . '{if (NF>1) {print $NF}}')
That will store in $file_ext the output of the command.
You have to be careful when declaring variables.
variable1="string" # assign a string value
variable3=`command` # assign output from command
variable2=$(command) # assign output from command
Notice that you cannot put a space after the variable, because then it gets interpreted as a normal command.

Resources