Rename a file in linux which has date appended to it - linux

There is a single file in a folder which has date and time appended to it. I would like to rename it to something else so that I can access it easily. I know the starting word of this file name. Is they there a way I can rename this (using wildcard or something)? . Can't use Tab since I am trying to write a script to automate something.
Also, I would like to access the lexicographical last element and rename it if there are multiple files.

You want to find the last changed file in a directory? Which matches a pattern?
find . -maxdepth 1 -mindepth 1 -type f -name "prefix*" \
-printf "%TY%Tm%TdTH%TM %p\n" | sort -nr | read -r _ file
printf "%s" "$file"
Assuming no filename contains newlines. And that you actually just want to get the last changed file in a directory.
Alternative you can sort do something like this:
find . -maxdepth 1 -mindepth 1 -type f -name "prefix*" | sort -nr -t- -k2
Which will sort files like this:
prefix-2016-05-05
prefix-2016-06-05
prefix-2016-04-08
To
prefix-2016-06-05
prefix-2016-05-05
prefix-2016-04-08

Assuming the name of the file is bob_2016-06-10_06:00:00.txt you could do this:
mv *_20[0-9][0-9]-[01][0-9]-[0-3][0-9]_[0-2][0-9]:[0-5][0-9]:[0-5][0-9].txt commmonname.txt

You can use rename with a regexp. The syntax is:
Usage: rename [-v] [-n] [-f] perlexpr [filenames]
So, given the following files:
coda#pong:/tmp/kk$ ls -l
total 0
-rw-rw-r-- 1 coda coda 0 Jun 10 13:28 aaaa-2016-01-01.txt
-rw-rw-r-- 1 coda coda 0 Jun 10 13:28 aaaa-2016-01-02.txt
-rw-rw-r-- 1 coda coda 0 Jun 10 13:28 aaaa-2016-01-03.txt
-rw-rw-r-- 1 coda coda 0 Jun 10 13:28 aaaa-2016-01-04.txt
You can rename them this way:
coda#pong:/tmp/kk$ rename -v 's/aaaa/xxxx/' *.txt
aaaa-2016-01-01.txt renamed as xxxx-2016-01-01.txt
aaaa-2016-01-02.txt renamed as xxxx-2016-01-02.txt
aaaa-2016-01-03.txt renamed as xxxx-2016-01-03.txt
aaaa-2016-01-04.txt renamed as xxxx-2016-01-04.txt
If you want to keep track of the lexicographical last element, I would use something like this in the script:
ln -sf `ls | tail -n1` latest
Since ls sorts by name by default, you will always have a link to your lexicographical last element:
coda#pong:/tmp/kk$ ls -lrt
total 0
-rw-rw-r-- 1 coda coda 0 Jun 10 13:28 xxxx-2016-01-01.txt
-rw-rw-r-- 1 coda coda 0 Jun 10 13:28 xxxx-2016-01-02.txt
-rw-rw-r-- 1 coda coda 0 Jun 10 13:28 xxxx-2016-01-03.txt
-rw-rw-r-- 1 coda coda 0 Jun 10 13:28 xxxx-2016-01-04.txt
lrwxrwxrwx 1 coda coda 19 Jun 10 13:59 latest -> xxxx-2016-01-04.txt

Related

How to create a patch file for text files only in a directory

I have a directory with hundreds of text files and object files. I had a copy of this directory somewhere else and I edited it and recompiled it. the object files are now different, but I want to generate a patch from the text files only. is there a way to do this or do I need to separate them into different folders?
diff -uraN original/ new/ > patch.diff
how can I specify file types in this command?
-X excludes, but I want the opposite of this. I want to exclude everything except .txt files
Did you want one diff per txt?
for f in original/*.txt # for each original
do d=${f#original/} # get base name
diff -uraN "$f" "new/$d" > ${d%.txt}.diff # diff old against new
done
You mention -X; I'm not sure how diff implements it, but the bash CLI allows extended globbing.
$: shopt -s extglob
$: ls -l *.???
-rw-r--r-- 1 P2759474 1049089 0 May 10 21:49 OCG3C82.tmp
-rw-r--r-- 1 P2759474 1049089 0 May 11 03:22 OCG511D.tmp
-rw-r--r-- 1 P2759474 1049089 0 May 12 00:03 OCG5214.tmp
-rw-r--r-- 1 P2759474 1049089 0 May 14 09:34 a.txt
-rw-r--r-- 1 P2759474 1049089 0 May 14 09:34 b.txt
$: ls *.!(txt)
-rw-r--r-- 1 P2759474 1049089 0 May 10 21:49 OCG3C82.tmp
-rw-r--r-- 1 P2759474 1049089 0 May 11 03:22 OCG511D.tmp
-rw-r--r-- 1 P2759474 1049089 0 May 12 00:03 OCG5214.tmp
If I understand your question correctly, you just want to perform the diff command on any files with the extension .txt.
Unfortunately, diff has no include option, but we can get around it by using find to get a list of the files which aren't text files, and then we can exclude those using -X. This one liner will do that.
find original new ! -name '*.txt' -printf '%f\n' -type f | diff -uraN original/ new/ -X - > patch.diff
If you want more info on how that works you can check out the man pages for find and diff.

replacement on xargs variable returns empty string

I need to search for XML files inside a directory tree and create links for them on another directory (staging_ojs_pootle), naming these links with the file path (replacing slashes per dots).
the bash command is not working, I got stuck on the replacement part. Seems like the variable from xargs, named 'file', is not accessible inside the replacement code (${file/\//.})
find directory/ -name '*.xml' | xargs -I 'file' echo "ln" file staging_ojs_pootle/${file/\//.}
The replacement inside ${} result gives me an empty string.
Tried using sed but regular expressions were replacing all or just the last slash :/
find directory/ -name '*.xml' | xargs -I 'file' echo "ln" file staging_ojs_pootle/file |sed -e '/^ln/s/\(staging_ojs_pootle.*\)[\/]\(.*\)/\1.\2/g'
regards
Try this:
$ find directory/ -name '*.xml' |sed -r 'h;s|/|.|g;G;s|([^\n]+)\n(.+)|ln \2 staging_ojs_pootle/\1|e'
For example:
$ mkdir -p /tmp/test
$ touch {1,2,3,4}.xml
# use /tmp/test as staging_ojs_pootle
$ find /tmp/test -name '*.xml' |sed -r 'h;s|/|.|g;G;s|([^\n]+)\n(.+)|ln \2 /tmp/test/\1|e'
$ ls -al /tmp/test
total 8
drwxr-xr-x. 2 root root 4096 Jun 15 13:09 .
drwxrwxrwt. 9 root root 4096 Jun 15 11:45 ..
-rw-r--r--. 2 root root 0 Jun 15 11:45 1.xml
-rw-r--r--. 2 root root 0 Jun 15 11:45 2.xml
-rw-r--r--. 2 root root 0 Jun 15 11:45 3.xml
-rw-r--r--. 2 root root 0 Jun 15 11:45 4.xml
-rw-r--r--. 2 root root 0 Jun 15 11:45 .tmp.test.1.xml
-rw-r--r--. 2 root root 0 Jun 15 11:45 .tmp.test.2.xml
-rw-r--r--. 2 root root 0 Jun 15 11:45 .tmp.test.3.xml
-rw-r--r--. 2 root root 0 Jun 15 11:45 .tmp.test.4.xml
# if don NOT use the e modifier of s command, we can get the final command
$ find /tmp/test -name '*.xml' |sed -r 'h;s|/|.|g;G;s|([^\n]+)\n(.+)|ln \2 /tmp/test/\1|'
ln /tmp/test/1.xml /tmp/test/.tmp.test.1.xml
ln /tmp/test/2.xml /tmp/test/.tmp.test.2.xml
ln /tmp/test/3.xml /tmp/test/.tmp.test.3.xml
ln /tmp/test/4.xml /tmp/test/.tmp.test.4.xml
Explains:
for each xml file, use h to keep the origin filename in hold space.
the use s|/|.|g to substitute all / to . for xml filename.
use G to append the hold space to pattern space, then pattern space is CHANGED_FILENAME\nORIGIN_FILENAME.
use s|([^\n]+)\n(.+)|ln \2 staging_ojs_pootle/\1|e' to merge the command with CHANGED_FILENAME and ORIGIN_FILENAME, then use e modifier of s command to execute the command assembled above, which will do the actual works.
Hope this helps!
If you can be sure that the names of your XML files do not contain any word-splitting characters, you can use something like:
find directory -name "*.xml" | sed 'p;s/\//./' | xargs -n2 echo ln

how to get previous date files and pass ls output to array in gawk

I have log files like below generated, and I need to daily run script ,which will list them , and then do 2 things.
1- get previous / yesterday files and transfer them to x server
2- get files older than one day and transfer them to y server
files are like below and I am trying below code but not working.
how can we pass ls -altr output to gawk ? can we built an associate array like below.
array[index]=ls -altr | awk '{print $6,$7,$8}'
code I am trying to retrieve previous date files , but not working
previous_dates=$(date -d "-1 days" '+-%d')
ls -altr |gawk '{if ( $7!=previous_dates ) print $9 }'
-r-------- 1 root root 6291563 Jun 22 14:45 audit.log.4
-r-------- 1 root root 6291619 Jun 24 09:11 audit.log.3
drwxr-xr-x. 14 root root 4096 Jun 26 03:47 ..
-r-------- 1 root root 6291462 Jun 26 04:15 audit.log.2
-r-------- 1 root root 6291513 Jun 27 23:05 audit.log.1
drwxr-x---. 2 root root 4096 Jun 27 23:05 .
-rw------- 1 root root 5843020 Jun 29 14:57 audit.log
To select files modified yesterday, you could use
find . -daystart -type f -mtime 1
and to select older files, you could use
find . -daystart -type f -mtime +1
possibly adding a -name test to select only files like audit.log*, for example. You could then use xargs to process the files, e.g.
find . -daystart -type f -mtime 1 | xargs -n 1 -I{} scp {} user#server

Open all files in Sublime Text from a directory except ones explicitly specified

I know that we can use this command find . -type f ! -name '[PATTERN]' to find all files in the current directory except the ones that match the specified search pattern, but what do I do to feed the files so found as command-line arguments into the Sublime Text editor to open them up in there?
misha#hp-laptop:~/work/cpp/class$ ls -l
total 28
-rwxrwxr-x 1 misha misha 14252 Mar 24 00:49 out
-rw-rw-r-- 1 misha misha 236 Mar 24 00:48 Person.cpp
-rw-rw-r-- 1 misha misha 255 Mar 24 00:49 Person.h
-rw-rw-r-- 1 misha misha 200 Mar 24 00:49 test.cpp
misha#hp-laptop:~/work/cpp/class$ find . -type f ! -name 'out'
./Person.h
./test.cpp
./Person.cpp
misha#hp-laptop:~/work/cpp/class$
For this, xargs is your friend! It allows you to turn lines from STDIN into parameters.
Assuming you can open files with sublime some_file some_other_file ..., you can use:
find . -type f ! -name 'out' | xargs sublime
In your case, it will take the output from find
./Person.h
./test.cpp
./Person.cpp
And append them to sublime to build and run a command:
sublime ./Person.h ./test.cpp ./Person.cpp

Linux combine sort files by date created and given file name

I need to combine these to commands in order to have a sorted list by date created with the specified "filename".
I know that sorting files by date can be achieved with:
ls -lrt
and finding a file by name with
find . -name "filename*"
I don't know how to combine these two. I tried with a pipeline but I don't get the right result.
[EDIT]
Not sorted
find . -name "filename" -printf '%TY:%Tm:%Td %TH:%Tm %h/%f\n' | sort
Forget xargs. "Find" and "sort" are all the tools you need.
My best guess would be to use xargs:
find . -name 'filename*' -print0 | xargs -0 /bin/ls -ltr
There's an upper limit on the number of arguments, but it shouldn't be a problem unless they occupy more than 32kB (read more here), in which case you will get blocks of sorted files :)
find . -name "filename" -exec ls --full-time \{\} \; | cut -d' ' -f7- | sort
You might have to adjust the cut command depending on what your version of ls outputs.
Check the below-shared command:
1) List Files directory with Last Modified Date/Time
To list files and shows the last modified files at top, we will use -lt options with ls command.
$ ls -lt /run
output
total 24
-rw-rw-r--. 1 root utmp 2304 Sep 8 14:58 utmp
-rw-r--r--. 1 root root 4 Sep 8 12:41 dhclient-eth0.pid
drwxr-xr-x. 4 root root 100 Sep 8 03:31 lock
drwxr-xr-x. 3 root root 60 Sep 7 23:11 user
drwxr-xr-x. 7 root root 160 Aug 26 14:59 udev
drwxr-xr-x. 2 root root 60 Aug 21 13:18 tuned
https://linoxide.com/linux-how-to/how-sort-files-date-using-ls-command-linux/

Resources