I have a file called alldatalist.txt
that contains:
../19970327/datalist.txt
../19970328/datalist.txt
../19970329/datalist.txt
../19970330/datalist.txt
../19970331/datalist.txt
../19970401/datalist.txt
../19970402/datalist.txt
../19970403/datalist.txt
../19970404/datalist.txt
../19970405/datalist.txt
Each file (or row in alldatalist.txt
) has its own content (for instance the first file/row):
$ cat ../19970327/datalist.txt
19970327_0100.xyz
19970327_0200.xyz
19970327_0300.xyz
19970327_0400.xyz
19970327_0500.xyz
I've been scratching my head trying to print the latter with the "outer" path from the alldatalist.txt
file, so to get this:
../19970327/19970327_0100.xyz
../19970327/19970327_0200.xyz
../19970327/19970327_0300.xyz
../19970327/19970327_0400.xyz
../19970327/19970327_0500.xyz
cat alldatalist.txt | xargs cat
produces the content of each file (or row in alldatalist.txt
) without the desired path, so I may include the paste
cut
(or basename
) tools to add each path using a for loop, but it seems that it may be an overcomplex solution. I was wondering if you can suggest me a trick to add that path in a cleaner and/or simpler way.
Any support is appreciated.
CodePudding user response:
You can just add the base directory name to the start of each line in the file and print the contents (Make sure that the directory name doesn't conflict with sed, if it does you could use the r
command of sed to read safely from a file containing the dirname):
while read -r line; do
dir="$(dirname "$line")/"
sed "s|^|$dir|g" < "$line"
done < alldatalist.txt
CodePudding user response:
You could easily do this with a shell loop and sed
:
while IFS= read -r filename; do
b=${filename%/*}
sed "s%^%$b%" "$filename"
done < alldatalist.txt
or similarly with xargs
and Awk:
xargs -a alldatalist.txt awk '
FNR==1 { b = FILENAME; sub(/[^\/]*$/, "", b) }
{ print b $0 }'
In the shell loop, the shell parameter expansion ${variable%pattern}
produces the value of variable
with any match on pattern
removed from the end. There is similarly a ${variable#pattern}
prefix substitution; see the manual for details.
Because the replacement string contains a literal slash, we use %
as the pattern delimiter in sed
instead; see also Using different delimiters in sed commands and range addresses
In the Awk script, we use xargs
to feed awk
as many file names from the file as will fit on its command line, and run the Awk script on all of those. The FNR
variable contains the line (or more generally record) number within the current file; so on the first line of each file, we recalculate the value of b
, which is then printed as a prefix on all output lines.