0

I have a long list of folders, inside every folder I have the file "log.dat". I wanted to read the value of a specific line inside this file. I saved the folders names in a file "All.txt", in the parent folder, then I ran this code:

#!/bin/bash
in=/a/b/c   #path to the file All.txt  
for i in $(cat $in/all.txt); do
sed -n '/price/p' ${in}/${i}/log.dat

done

This code was able to read almost all the files but for some reason, which I can't figure it out!! It was output the following error message:

/log.dat: No such file or directory #(then the path to this file)

If I run the command sed -n '/price/p' log.dat inside the folder that output the error message. I get an answer!

PS: The content of the file ALL.txt ( which is created by running the command ls>All.txt in the parent folder) is as follow:

STR-548-021-01
STR-548-021-02
STR-548-022-01
STR-548-022-02
STR-548-023-01
STR-548-023-02
.
.
.
.
.

I tried to use the command "awk" instead of "sed" as follow:

awk '{ price }' ${in}/${i}/log.dat

And I got the same error message.

Can these carriage returns happen in Linux as an output for the command ls>All.txt?

  • @don_crissti. Thanks! Kindly, How can I use "xargs" instead? Also, This command worked very well for almost all my files. Why it is unable to read some of them. They all identical –  May 01 '16 at 23:11
  • there are no trailing spaces! –  May 01 '16 at 23:24
  • I got the same error message stating that there is no file or directory –  May 01 '16 at 23:34
  • find ./ -iname log.dat -print0 | sort -z | xargs -0 -L 1 sed -n '/price/p' | tee result.dat xargs use, like that as example – MolbOrg May 01 '16 at 23:36
  • @ MolbOrg. Thanks!. I got with xargs, the same error message –  May 01 '16 at 23:44
  • try the same, but find ./ -iname log.dat -type f -readable -print0 – MolbOrg May 01 '16 at 23:49

2 Answers2

1

There are carriage returns at the end of $i, because there are carriage returns at the end of the lines in all.txt. It was probably produced on Windows: Windows uses the two-character sequence CR,LF to mark a line break, whereas Unix (and most of the rest of the world) uses just LF (linefeed, synonym of newline in the Unix world), so Unix sees a line with a CR at the end.

Either convert your file to Unix line endings, or strip off the CR:

for i in $(cat $in/all.txt); do
  i=${i%$'\r'}
  sed -n '/price/p' ${in}/${i}/log.dat
done

This does nothing if there's no CR at the end of a line. Explanation: $'\r' is a carriage return, and ${i%…} is the value of i minus the specified suffix

Note that your script expects blank-separated input, not one file per line, and the input is a list of wildcard patterns, not file names. See Why does my shell script choke on whitespace or other special characters? . This makes no difference if there are no spaces or wildcards in the input.

0

Your error message indicates that sed is getting an argument of /log.dat - neither $i or $in are set to any value. I think you have a blank line in your All.txt file.

/log.dat: No such file or directory #(then the path to this file)

  • You are right. it is something related to the file ALL.txt. But it is also something that I was unable to understand!!! The folders names are sorted bellow each other and no blanck spaces between them. I did back slash for the foloowing line to the folder name that output the error then I pressed enter and every thing went fine. Why ? –  May 01 '16 at 23:52
  • No, if the variables were unset, that would be //log.dat. They're set — but the last one ends with a CR which causes the end of the file name to overwrite the beginning of the line. – Gilles 'SO- stop being evil' May 01 '16 at 23:53