It is required to make a simple script that displays the name of the file and then its contents in the specified directory. I tried to modify the example from the manual:

cd $1 for f in *.txt do cat ${f} done 

However, an error occurs when starting

 xred@xred-W65-67SJ:~$ ./7.sh /home/ cat: '*.txt': No such file or directory 

What am I doing wrong? The home directory is guaranteed to have several files with this extension.

    3 answers 3

    @Xred "What am I doing wrong?"

     #!/usr/bin/bash path_to_dir="$1" ls -R "${path_to_dir}"/*.txt \ | while read -r txt_file; do echo "$txt_file" cat "$txt_file" done # End of script 

    In the current directory, a global path value is sufficient:

     ~$ cat ./*.txt 

    A single find or grep recursively suffices:

     ~$ find ./ -type f -name "*.txt" -print -exec cat {} \; ~$ grep -r ".*" ./**/*.txt 

    Checked using:

    • GNU coreutils
    • GNU findutils
    • GNU grep
    • And where to screw $ 1 to pass the path as a command line argument? - Xred
    • I will correct the answer. - Hellseher
     find PATH_DIR -type f | while read FN; do echo $FN; cat $FN; done; 
    • 2
      or find PATH_DIR -type f -exec echo {} ";" -exec cat {} ";" find PATH_DIR -type f -exec echo {} ";" -exec cat {} ";" - Mike
    1. There are usually no files in the /home directory. therefore, nothing is found. You probably wanted to specify the home directory of a user. the default is the directory /home/имя_пользователя .
    2. in order not to receive an error message in case there are really no files matching the mask, in addition to the solutions suggested in other answers, you can set the option nullglob at the beginning of the script:

       shopt -s nullglob 

      Its meaning is that if not a single file system object falls under the specified mask (for example, *.txt ) (that is, there are neither files, nor directories, nor symbolic links whose names end with .txt characters), then the result of the substitution will not be the mask itself - *.txt (this happens by default), but an empty string.

      but be careful. for example, if there are no files in the directory that match the mask, a command like ls *.txt will return the entire contents of the directory, as if the ls program was called without any parameter at all. but the for f in *.txt; do тело-цикла; done command for f in *.txt; do тело-цикла; done for f in *.txt; do тело-цикла; done for f in *.txt; do тело-цикла; done work as expected - the loop body will not be executed once.