Home > Enterprise >  Including path to the content of a file
Including path to the content of a file

Time:09-22

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.

  • Related