How to: compare command output to text file with bash - linux

I'm trying to compare the output of the command
`ls -l directory`
with a file that I've created using the same command. (I'm trying a poor man's way of making sure no files have been modified.)
The trouble is, I don't know how to diff the output of the ls command with the file that I've created. I've tried the following and each time it doesn't work
diff file.ls <(ls -l directory)
ls -l directory | xargs diff file.ls
ls -l directory | diff file.ls
diff file.ls < `ls -l directory`
What is the magic command to compare the output of ls to a file that I've already saved?

The answer (for posterity) is to do the following
diff file.ls <(ls -l directory)
When I did this previously, the output was blank. I thought I had done it wrong; in actuality there was no difference between the contents of the directory and my file.
<\facepalm>

diff is easiest when you compare files.
$ ls $DIR > original.ls
do some stuff
$ ls $DIR > new.ls
$ diff original.ls new.ls

Related

Trying to diff two files with generated paths - no such file or directory - but files exist

I want to diff two files in the same directory in a bash script. To get the full paths of these two files (I need this because the script isn't running the same directory), I did:
pathToOld=$(ls -Art /dir/path/here | grep somestring | tail -n2 | head -n1)
pathToOld="/dir/path/here/${pathToOld}"
and
pathToNew=$(ls -Art /dir/path/here | grep somestring | tail -n 1)
pathToNew="/dir/path/here/${pathToNew}"
I was able to figure out the above from the following links: link1, link2, link3
If I echo these path in the .sh script, it comes out correctly, like:
>echo "${pathToOld}"
/dir/path/here/oldFile
But when I try to diff the files like so:
diff pathToOld pathToNew
It tells me:
diff: pathToOld: No such file or directory
diff: pathToNew: No such file or directory
How do I make this work?
Btw, I have also tried to pipe sed -z 's/\n/ /g' (inspired by this) to both lines but that hasn't helped.

Linux commands to get Latest file depending on file name

I am new to linux. I have a folder with many files in it and i need to get the latest file depending on the file name. Example: I have 3 files RAT_20190111.txt RAT_20190212.txt RAT_20190321.txt . I need a linux command to move the latest file here RAT20190321.txt to a specific directory.
If file pattern remains the same then you can try below command :
mv $(ls RAT*|sort -r|head -1) /path/to/directory/
As pointed out by #wwn, there is no need to use sort, Since the files are lexicographically sortable ls should do the job already of sorting them so the command will become :
mv $(ls RAT*|tail -1) /path/to/directory
The following command works.
ls | grep -v '/$' |sort | tail -n 1 | xargs -d '\n' -r mv -- /path/to/directory
The command first splits output of ls with newline. Then sorts it, takes the last file and then it moves this to the required directory.
Hope it helps.
Use the below command
cp ls |tail -n 1 /data...

Printing the number of lines

I have a directory that contains only .txt files. I want to print the number of lines for every file. When I write cat file.txt | wc -l the number of lines appears but when I want to make a script it's more complicated. I have this code:
for fis in `ls -R $1`
do
echo `cat $fis | wc -l`
done
I tried: wc -l $fis , with awk,grep and it doesn't work. It tells that:
cat: fis1: No such file or directory
0
How can I do to print the number of lines?
To find files recursively in subdirectories, use the find command, not ls -R, which is mainly intended for human reading.
find "$1" -type f -exec wc -l {} +
The problems with looping over the output of ls -R are:
Filenames with whitespace won't be parsed correctly.
It prints other output beside just the filenames.
Not the problem here, but the echo command is more than needed:
You can use
wc -l "${fis}"
What goes wrong?
You have a subdir called fis1. Look to the output of ls:
# ls -R fis1
fis1:
file1_in_fis1.txt
When you are parsing this output, your script will try
echo `cat fis1: | wc -l`
The cat will tell you No such file or directory and wc counts 0.
As #Barmar explained, ls prints additional output you do not want.
Do not try to patch your attempt by | grep .txt and if [ -f "${fis}"]; then .., these will fail with filename with spaces.txt. So use find or shopt (and accept the answer of #Barmar or #Cyrus).

ls in a directory for a list of files

I have a C codebase, all resides in the same directory.
I want to find all the header files that have a code file with the same name.
Right now, I have the following command:
ls *.h | sed s/.h/.c/
This returns a 'list' of filenames that I want to search for. How can I pass this list to another command so that I can see which header files have code files sharing the same name?
Without any external command:
$ for i in *.h
> do
> [ -f ${i/.h/.c} ] && echo $i
> done
The first line loops through every file.
The third line is a test construct. The -f flag to test (aka man [) checks to see if the file exists. If it does, it returns 0 (which is considered true in shell). The && only operates if the following command if the previous line returned successfully.
${i/.h/.c} is an in-place in-shell regex substitution so that the file tested is the corresponding .c to the .h.
you could use xargs which transforms its input:
a
b
c
to an argument list:
a b c
So this should print "a b c":
echo -e "a\nb\nc" | xargs echo
ls `ls *.h|sed s/.h/.c/` 2>/dev/null
should do the trick
ls -1 *.c* *.h*|awk -F. '{a[$1]++}END{for(i in a){if(a[i]==2)print i".hh"} }'
ls *.h | sed s/.h/.c/ | xargs ls 2>/dev/null
The remainder of the command runs ls again with the new *.c filenames. ls will complain about every file that doesn't exist, so we redirect stderr to nowhere.
Example without 2>/dev/null:
$ ls
a.c a.h b.c c.c d.h
$ ls *.h | sed s/.h/.c/ | xargs ls
ls: d.c: No such file or directory
a.c

Linux: cat matching files in date order?

I have a few files in a directory with names similar to
_system1.log
_system2.log
_system3.log
other.log
but they are not created in that order.
Is there a simple, non-hardcoded, way to cat the files starting with the underscore in date order?
Quick 'n' dirty:
cat `ls -t _system*.log`
Safer:
ls -1t _system*.log | xargs -d'\n' cat
Use ls:
ls -1t | xargs cat
ls -1 | xargs cat
You can concatenate and also store them in a single file according to their time of creation and also you can specify the files which you want to concatenate. Here, I find it very useful. The following command will concatenate the files which are arranged according to their time of creaction and have common string 'xyz' in their file name and store all of them in outputfile.
cat $(ls -t |grep xyz)>outputfile

Resources