LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - General
User Name
Password
Linux - General This Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.

Notices


Reply
  Search this Thread
Old 04-03-2020, 04:21 AM   #1
Drosera_capensis
Member
 
Registered: Jun 2018
Posts: 153

Rep: Reputation: Disabled
awk and sed headaches


Hello everyone, I am trying to set up a nested while loop to select a string of text and print the string row the row after as an output.

I could not manage to do it with awk, as it print the whole document ($0?) and not only the string and the line below.
Code:
cat list_1 | while read g;  
 do
  cat list_2 | while read s;
   do 
    touch ./output/$g
    awk '$0==$s {print $0}' ./*/*/$g > ./output/$g ;
  done
done
I have tried as well with sed, and this command does not work with a variable, where it works with /regexp/.

Code:
cat list_1 | while read g;  
do
 cat list_2 | while read s;
  do 
   touch ./output/$g
   sed -n '/$s/, +1p' ./*/*/$g > ./output/$g ; 
  done
done
Could you indicate me what could be the mistake here?
 
Old 04-03-2020, 04:32 AM   #2
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,844

Rep: Reputation: 7309Reputation: 7309Reputation: 7309Reputation: 7309Reputation: 7309Reputation: 7309Reputation: 7309Reputation: 7309Reputation: 7309Reputation: 7309Reputation: 7309
yes, both awk and sed can read stdin.
So the cat piped into while will be first read by while, but afterward the sed or awk will continue to read it and the while will not get anything more ....
You need to close stdin like:
Code:
sed .... </dev/null > file
# or
awk .... </dev/null > file
furthermore $s is not evaluated between ' signs.
Would be nice to use shellcheck to check your script.
 
Old 04-03-2020, 04:53 AM   #3
Turbocapitalist
LQ Guru
 
Registered: Apr 2005
Distribution: Linux Mint, Devuan, OpenBSD
Posts: 7,308
Blog Entries: 3

Rep: Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721
The single quotes mean that the string is literal not interpreted. Thus above you have an actual $s being passed to AWK instead of the contents of $s. If you use double quotes, then you will have to escape the AWK built-in variables such as $0. Instead you might look at the -v, aka --assign, option:

Code:
cat list_1 | while read g;  
 do
  cat list_2 | while read s;
   do 
    touch ./output/$g
    awk --assign s="$s" '$0==s {print $0}' ./*/*/$g > ./output/$g ;
  done
done
Or maybe (untested)

Code:
cat list_1 | while read g;  
 do
  touch ./output/$g
  awk 'NR==FNR {a[$0]++; next} a[$0] {print $0}' list_2 ./*/*/$g > ./output/$g ;
done
The double-quote versus single quote difference also applies to sed too.
 
Old 04-04-2020, 06:26 AM   #4
Drosera_capensis
Member
 
Registered: Jun 2018
Posts: 153

Original Poster
Rep: Reputation: Disabled
Thank you very much for your answers. The following script is almost working Turbocapitalist, thanks.
The matches /regexp/ are printed along with the following line (getline).
But, there is still a single line of no-match printed (without the second line).
Would you have an idea why?

Code:
cat list_1 | while read g;  
 do
  cat list_2 | while read s;
   do 
    touch ./output/$g
    awk --assign s="$s" '$0==s {print $0; getline; print $0}'  ./*/*/$g > ./output/$g ;
  done
done
Thanks for the links pan64. I have used shellcheck and it looks a formidable tool. Except that some advises it gives are not compatible with the command.
For exemple, replacing:
Code:
cat list_1 | while read g
with:
Code:
while read g < list_1
Is preventing the command to work. Same thing for the advice to put all the variables between double quotes "$g". I guess it is a tool to use carefully.
 
Old 04-04-2020, 06:52 AM   #5
Turbocapitalist
LQ Guru
 
Registered: Apr 2005
Distribution: Linux Mint, Devuan, OpenBSD
Posts: 7,308
Blog Entries: 3

Rep: Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721
Quote:
Originally Posted by Drosera_capensis View Post
Thank you very much for your answers. The following script is almost working Turbocapitalist, thanks.
The matches /regexp/ are printed along with the following line (getline).
But, there is still a single line of no-match printed (without the second line).
Would you have an idea why?
It is a little hard now to visualize your goal. Can you show a handful of lines from each of the two files, sanitized if necessary, along with the output you desire?
 
Old 04-04-2020, 08:43 AM   #6
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,844

Rep: Reputation: 7309Reputation: 7309Reputation: 7309Reputation: 7309Reputation: 7309Reputation: 7309Reputation: 7309Reputation: 7309Reputation: 7309Reputation: 7309Reputation: 7309
Quote:
Originally Posted by Drosera_capensis View Post
Code:
cat list_1 | while read g
with:
Code:
while read g < list_1
Is preventing the command to work.
yes, would be nice to explain better, that should work
Quote:
Originally Posted by Drosera_capensis View Post
Same thing for the advice to put all the variables between double quotes "$g". I guess it is a tool to use carefully.
Again, what shellcheck suggests is usually really good. There is always a help for every suggestion, so you can easily understand the reason and also the possible exceptions.
 
Old 04-04-2020, 11:23 AM   #7
teckk
LQ Guru
 
Registered: Oct 2004
Distribution: Arch
Posts: 5,137
Blog Entries: 6

Rep: Reputation: 1826Reputation: 1826Reputation: 1826Reputation: 1826Reputation: 1826Reputation: 1826Reputation: 1826Reputation: 1826Reputation: 1826Reputation: 1826Reputation: 1826
Quote:
while read g < list_1
Code:
echo -e "One\nTwo\nThree\nFour" > MyTest.txt

while read g; do
    echo "$g"
done < MyTest.txt

One
Two
Three
Four
 
Old 04-05-2020, 05:29 AM   #8
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 2,792

Rep: Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201
Code:
while read g < list_1
The redirection is for the read command.
Because it is within the while loop, it opens the file (and reads the 1st line) for each loop cycle.
In contrast, the following redirects the entire loop
Code:
while
  read g
do
  ...
done < list_1
The shell opens the file once and redirects stdin.
Now each command that reads from stdin actually reads from the file. For each loop cycle the read command reads a new line.
The file is closed when the loop terminates, at the end or by a break.

For the advanced users:
the early Bourne shell allowed to switch order
Code:
< list_1 read
And all shells are compatible.
But only the zsh does, as a logical consequence, allow the same for a code block:
Code:
< list_1 while
  read g
do
  ...
done
Not only while-do-done is a code block.
Also for-do-done and if-then-fi are code blocks.
And { } is an artificial code block. An example:
Code:
{
read line1
while
  read line
do
  ...
done
} < inputfile
Again only zsh allows
Code:
< inputfile {
...
}
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] sed inside awk or awk inside awk maddyfreaks Linux - Newbie 4 06-29-2016 01:10 PM
[SOLVED] Once again... awk.. awk... awk shivaa Linux - Newbie 13 12-31-2012 04:56 AM
SED to replace and headaches: Is there a tar.gz for any Alternatives , accepted ! frenchn00b Programming 9 09-19-2009 01:19 AM
of Netbios and vpn headaches scheidel21 Linux - Networking 9 03-11-2003 10:55 PM
glibc and libgthread... A no-sleep night and few headaches later... Half_Elf Linux - Software 2 10-18-2002 06:45 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - General

All times are GMT -5. The time now is 12:40 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration