Rename or remove prefix for multiple files to each ones' number in Windows - windows

I am trying to change all the files names in a current folder and I am trying to achieve this either by removing the files prefix (every file has a common prefix) or changing their names to their count (if there are 5 files, the filenames will be 1.txt 2.txt 3.txt 4.txt 5.txt).
Now I have found the ren command in cmd and played with it a little but so far I was not able to achieve the result and I can only run this in cmd, so no batch files can be used.
This is the closest that I got, but it only adds a prefix:
FOR %f IN (*.*) DO ren %f prefix%f
I have tried doing the opposite:
FOR %f IN (*.*) DO ren prefix%f %f
But of course, didn't work so I am now asking for help and some explanation if possible (I like to understand how these things work). Thanks in advance for any help.

A much simpler solution is provided in
https://superuser.com/a/871799/497147
I copied it here for easier access.
Forget about complicated scripts for this.
rename is a very old and never properly completed command. If you do not use it properly, the result might surprise you.
For example to remove a prefix abcd from abcd1.txt, abcd2.txt, abcd3.txt etc. in order to get 1.txt, 2.txt, 3.txt simply use
rename "abcd*.txt" "////*.txt"
You need the same number of / as the number of initial characters you would like to remove.
Do place double quotes for both arguments.

I don't understand why you can't use a batch file. But here is a solution that should work with most file names.
Critical - first you must make sure you have an undefined variable name, I'll use fname
set "fname="
Next is the command to actually do the renaming. It won't work properly if fname is already defined.
for %a in (prefix*.txt) do #(set "fname=%a" & call ren "%fname%" "%fname:*prefix=%")
The fname variable is defined for each iteration and then the syntax %fname:*prefix=% replaces the first occurrence of "prefix" with nothing. The tricky thing is Windows first attempts to expand %fname% when the command is first parsed. Of course that won't work because it hasn't been defined yet. On the command line the percents are preserved if the variable is not found. The CALL causes an extra expansion phase that occurs after the variable has been set, so the expansion works.
If fname is defined prior to running the command, then it will simply try to rename that same file for each iteration instead of the value that is being assigned within the loop.
If you want to run the command again with a different prefix, you will have to first clear the definition again.
EDIT - Here is a batch file named "RemovePrefix.bat" that does the job
::RemovePrefix.bat prefix fileMask
#echo off
setlocal
for %%A in ("%~1%~2") do (
set "fname=%%~A"
call ren "%%fname%%" "%%fname:*%~1=%%"
)
Suppose you had files named like "prefixName.txt", then you would use the script by executing
RemovePrefix "prefix" "*.txt"
The batch file will rename files in your current directory. The batch file will also have to be in your current directory unless the batch file exists in a directory that is in your PATH variable. Or you can specify the full path to the batch file when you call it.
The rules for expansion are different in a batch file. FOR variables must be referenced as %%A instead of %A, and %%fname%% is not expanded initially, instead the double percents are converted into single percents and then %fname% is expanded after the CALL. It doesn't matter if fname is already defined with the batch file. The SETLOCAL makes the definition of fname temporary (local) to the batch file.

You can do it this way (let's say your prefix is "AS"):
x=1; for k in AS*; do y=$((x++)); echo "mv ${k} ${k:0:2}$y.txt"; done
if you want to save extensions use this (pre-test):
x=1; for k in AS*; do y=$((x++)); echo "mv ${k} ${k:0:2}$y.${k#*.}"; done
if pre-test is OK then remove echo and code will run this time:
x=1; for k in AS*; do y=$((x++)); mv ${k} ${k:0:2}$y.txt; done
*for saving extensions (remove echo and code will run this time):
x=1; for k in AS*; do y=$((x++)); mv ${k} ${k:0:2}$y.${k#*.}; done
${k:0:2} --> first two letters of file 0 to 2...
${k#*.}--> extension of the file
I had a similar situation myself and solved it.
My files were like this:
1-6-4-20.txt onar.mol2 replace.py z.out z__06.mol2 z__09.mol2 z__12.mol2 z__15.mol2 z__18.mol2 z__27.mol2 z__30.mol2 z__33.mol2 z__36.mol2
make_com_files.py pt.dat valid.txt z.xyz z__07.mol2 z__10.mol2 z__13.mol2 z__16.mol2 z__25.mol2 z__28.mol2 z__31.mol2 z__34.mol2 z__37.mol2
makepymol.py pymol.pml x.py z__05.mol2 z__08.mol2 z__11.mol2 z__14.mol2 z__17.mol2 z__26.mol2 z__29.mol2 z__32.mol2 z__35.mol2
Note that there is no z_01.mol2 z_02.mol2 z_03.mol2 z_04.mol2 and z_19.mol2 z_20.mol2 etc.. so my z files are not in sequence. I can't get rid of the problem by omitting the z_* prefix. and also I have onar.mol2
Here is my solution:
pre-test using echo to see if it is working correctly:
x=1; for k in *.mol2; do y=$((x++)); echo "mv ${k%%.*}.mol2 $y.mol2"; done
output:
mv onar.mol2 1.mol2
mv z__05.mol2 2.mol2
mv z__05.mol2 2.mol2
mv z__06.mol2 3.mol2
mv z__07.mol2 4.mol2
mv z__08.mol2 5.mol2
mv z__09.mol2 6.mol2
mv z__10.mol2 7.mol2
mv z__11.mol2 8.mol2
mv z__12.mol2 9.mol2
mv z__13.mol2 10.mol2
mv z__14.mol2 11.mol2
mv z__15.mol2 12.mol2
mv z__16.mol2 13.mol2
mv z__17.mol2 14.mol2
mv z__18.mol2 15.mol2
mv z__25.mol2 16.mol2
mv z__26.mol2 17.mol2
mv z__27.mol2 18.mol2
mv z__28.mol2 19.mol2
mv z__29.mol2 20.mol2
mv z__30.mol2 21.mol2
mv z__31.mol2 22.mol2
mv z__32.mol2 23.mol2
mv z__33.mol2 24.mol2
mv z__34.mol2 25.mol2
mv z__35.mol2 26.mol2
mv z__36.mol2 27.mol2
mv z__37.mol2 28.mol2
seems correct then I can use this as a command for my aim (by removing echo):
x=1; for k in *.mol2; do y=$((x++)); mv ${k%%.*}.mol2 $y.mol2; done
RESULT: ls -ln:
-rwxrwxrwx 1 0 0 1695 Nov 18 12:07 1-6-4-20.txt
-rwxrwxrwx 1 0 0 1813 Nov 18 13:27 1.mol2
-rwxrwxrwx 1 0 0 2782 Nov 18 13:27 10.mol2
-rwxrwxrwx 1 0 0 2783 Nov 18 13:27 11.mol2
-rwxrwxrwx 1 0 0 2783 Nov 18 13:27 12.mol2
-rwxrwxrwx 1 0 0 2783 Nov 18 13:27 13.mol2
-rwxrwxrwx 1 0 0 2783 Nov 18 13:27 14.mol2
-rwxrwxrwx 1 0 0 2784 Nov 18 13:27 15.mol2
-rwxrwxrwx 1 0 0 2785 Nov 18 13:27 16.mol2
-rwxrwxrwx 1 0 0 2785 Nov 18 13:27 17.mol2
-rwxrwxrwx 1 0 0 2786 Nov 18 13:27 18.mol2
-rwxrwxrwx 1 0 0 2786 Nov 18 13:27 19.mol2
-rwxrwxrwx 1 0 0 2781 Nov 18 13:27 2.mol2
-rwxrwxrwx 1 0 0 2787 Nov 18 13:27 20.mol2
-rwxrwxrwx 1 0 0 2788 Nov 18 13:27 21.mol2
-rwxrwxrwx 1 0 0 2788 Nov 18 13:27 22.mol2
-rwxrwxrwx 1 0 0 2788 Nov 18 13:27 23.mol2
-rwxrwxrwx 1 0 0 2788 Nov 18 13:27 24.mol2
-rwxrwxrwx 1 0 0 2788 Nov 18 13:27 25.mol2
-rwxrwxrwx 1 0 0 2788 Nov 18 13:27 26.mol2
-rwxrwxrwx 1 0 0 2788 Nov 18 13:27 27.mol2
-rwxrwxrwx 1 0 0 2788 Nov 18 13:27 28.mol2
-rwxrwxrwx 1 0 0 2782 Nov 18 13:27 3.mol2
-rwxrwxrwx 1 0 0 2783 Nov 18 13:27 4.mol2
-rwxrwxrwx 1 0 0 2783 Nov 18 13:27 5.mol2
-rwxrwxrwx 1 0 0 2783 Nov 18 13:27 6.mol2
-rwxrwxrwx 1 0 0 2783 Nov 18 13:27 7.mol2
-rwxrwxrwx 1 0 0 2782 Nov 18 13:27 8.mol2
-rwxrwxrwx 1 0 0 2782 Nov 18 13:27 9.mol2
-rwxrwxrwx 1 0 0 1383 Nov 17 12:27 make_com_files.py
-rwxrwxrwx 1 0 0 5687 Nov 17 16:34 makepymol.py
-rwxrwxrwx 1 0 0 1206 Nov 17 11:36 pt.dat
-rwxrwxrwx 1 0 0 964 Nov 18 13:29 pymol.pml
-rwxrwxrwx 1 0 0 2288 Nov 18 13:27 replace.py
-rwxrwxrwx 1 0 0 1284 Nov 18 13:07 valid.txt
-rwxrwxrwx 1 0 0 3809 Nov 18 12:37 x.py
-rwxrwxrwx 1 0 0 19622334 Nov 18 04:11 z.out
-rwxrwxrwx 1 0 0 34717 Nov 18 12:37 z.xyz
enter code here
EXTRA:
and if I want my files as 00001.mol2 00002.mol2 etc, I can add this command too:
rename 's/\d+/sprintf("%05d",$&)/e' *.mol2
Here are my mol2 files:
-rwxrwxrwx 1 0 0 1813 Nov 18 13:27 00001.mol2
-rwxrwxrwx 1 0 0 2781 Nov 18 13:27 00002.mol2
-rwxrwxrwx 1 0 0 2782 Nov 18 13:27 00003.mol2
-rwxrwxrwx 1 0 0 2783 Nov 18 13:27 00004.mol2
-rwxrwxrwx 1 0 0 2783 Nov 18 13:27 00005.mol2
-rwxrwxrwx 1 0 0 2783 Nov 18 13:27 00006.mol2
-rwxrwxrwx 1 0 0 2783 Nov 18 13:27 00007.mol2
-rwxrwxrwx 1 0 0 2782 Nov 18 13:27 00008.mol2
-rwxrwxrwx 1 0 0 2782 Nov 18 13:27 00009.mol2
-rwxrwxrwx 1 0 0 2782 Nov 18 13:27 00010.mol2
-rwxrwxrwx 1 0 0 2783 Nov 18 13:27 00011.mol2
-rwxrwxrwx 1 0 0 2783 Nov 18 13:27 00012.mol2
-rwxrwxrwx 1 0 0 2783 Nov 18 13:27 00013.mol2
-rwxrwxrwx 1 0 0 2783 Nov 18 13:27 00014.mol2
-rwxrwxrwx 1 0 0 2784 Nov 18 13:27 00015.mol2
-rwxrwxrwx 1 0 0 2785 Nov 18 13:27 00016.mol2
-rwxrwxrwx 1 0 0 2785 Nov 18 13:27 00017.mol2
-rwxrwxrwx 1 0 0 2786 Nov 18 13:27 00018.mol2
-rwxrwxrwx 1 0 0 2786 Nov 18 13:27 00019.mol2
-rwxrwxrwx 1 0 0 2787 Nov 18 13:27 00020.mol2
-rwxrwxrwx 1 0 0 2788 Nov 18 13:27 00021.mol2
-rwxrwxrwx 1 0 0 2788 Nov 18 13:27 00022.mol2
-rwxrwxrwx 1 0 0 2788 Nov 18 13:27 00023.mol2
-rwxrwxrwx 1 0 0 2788 Nov 18 13:27 00024.mol2
-rwxrwxrwx 1 0 0 2788 Nov 18 13:27 00025.mol2
-rwxrwxrwx 1 0 0 2788 Nov 18 13:27 00026.mol2
-rwxrwxrwx 1 0 0 2788 Nov 18 13:27 00027.mol2
-rwxrwxrwx 1 0 0 2788 Nov 18 13:27 00028.mol2
-rwxrwxrwx 1 0 0 1695 Nov 18 12:07 1-6-4-20.txt
-rwxrwxrwx 1 0 0 1383 Nov 17 12:27 make_com_files.py
-rwxrwxrwx 1 0 0 5687 Nov 17 16:34 makepymol.py
-rwxrwxrwx 1 0 0 1206 Nov 17 11:36 pt.dat
-rwxrwxrwx 1 0 0 964 Nov 18 13:29 pymol.pml
-rwxrwxrwx 1 0 0 2288 Nov 18 13:27 replace.py
-rwxrwxrwx 1 0 0 1284 Nov 18 13:07 valid.txt
-rwxrwxrwx 1 0 0 3809 Nov 18 12:37 x.py
-rwxrwxrwx 1 0 0 19622334 Nov 18 04:11 z.out
-rwxrwxrwx 1 0 0 34717 Nov 18 12:37 z.xyz

Following is straight way to trim the prefix with rename for all the files
rename -d your_prefix *

Related

Negate in bash extended globs does not work

I am trying to list some selective files but want to exclude atop_20210428, but the following extended glob atop_20210#(3|4)*[0-4]*!(8)* does not exclude the file atop_20210428, what is the correction required in that?.
[root#server atop]# ls -lh atop_20210#(3|4)*[0-4]*!(8)*
-rw-r--r-- 1 root root 81M Mar 31 00:00 atop_20210330
-rw-r--r-- 1 root root 80M Apr 1 00:00 atop_20210331
-rw-r--r-- 1 root root 79M Apr 2 00:00 atop_20210401
-rw-r--r-- 1 root root 82M Apr 3 00:00 atop_20210402
-rw-r--r-- 1 root root 82M Apr 4 00:00 atop_20210403
-rw-r--r-- 1 root root 81M Apr 5 00:00 atop_20210404
-rw-r--r-- 1 root root 80M Apr 6 00:00 atop_20210405
-rw-r--r-- 1 root root 81M Apr 7 00:00 atop_20210406
-rw-r--r-- 1 root root 81M Apr 8 00:00 atop_20210407
-rw-r--r-- 1 root root 81M Apr 9 00:00 atop_20210408
-rw-r--r-- 1 root root 80M Apr 10 00:00 atop_20210409
-rw-r--r-- 1 root root 81M Apr 11 00:00 atop_20210410
-rw-r--r-- 1 root root 80M Apr 12 00:00 atop_20210411
-rw-r--r-- 1 root root 82M Apr 13 00:00 atop_20210412
-rw-r--r-- 1 root root 81M Apr 14 00:00 atop_20210413
-rw-r--r-- 1 root root 81M Apr 15 00:00 atop_20210414
-rw-r--r-- 1 root root 79M Apr 16 00:00 atop_20210415
-rw-r--r-- 1 root root 78M Apr 17 00:00 atop_20210416
-rw-r--r-- 1 root root 80M Apr 18 00:00 atop_20210417
-rw-r--r-- 1 root root 78M Apr 19 00:00 atop_20210418
-rw-r--r-- 1 root root 81M Apr 20 00:00 atop_20210419
-rw-r--r-- 1 root root 79M Apr 21 00:00 atop_20210420
-rw-r--r-- 1 root root 82M Apr 22 00:00 atop_20210421
-rw-r--r-- 1 root root 81M Apr 23 00:00 atop_20210422
-rw-r--r-- 1 root root 82M Apr 24 00:00 atop_20210423
-rw-r--r-- 1 root root 81M Apr 25 00:00 atop_20210424
-rw-r--r-- 1 root root 83M Apr 26 00:00 atop_20210425
-rw-r--r-- 1 root root 83M Apr 27 00:00 atop_20210426
-rw-r--r-- 1 root root 83M Apr 28 00:00 atop_20210427
-rw-r--r-- 1 root root 29M Apr 28 08:35 atop_20210428
I did turn on extglob already:
[root#server atop]# shopt -p extglob
shopt -s extglob
[root#server atop]#
[root#server atop]# shopt | grep extglob
extglob on
* is matching everything, so *!(8)* is always going to match everything - first !(8) will not match anything (match empty), then * will match everything.
atop_20210 #(3|4) * [0-4] * !(8) *
atop_20210 4 2 8
Why all the *? Remove them. You want to just match what you want to match, not to match anything in between. Just:
atop_20210#(3|4)[0-4]!(8)

How to touch files with different names and different date created

I am trying to create files with different date created:
$ touch -t 20{11..15}01120000 file_{1..5}.txt
$ ls -al
-rw-r--r-- 1 shinokada staff 0 Jan 12 2011 201201120000
-rw-r--r-- 1 shinokada staff 0 Jan 12 2011 201301120000
-rw-r--r-- 1 shinokada staff 0 Jan 12 2011 201401120000
-rw-r--r-- 1 shinokada staff 0 Jan 12 2011 201501120000
-rw-r--r-- 1 shinokada staff 0 Jan 12 2011 file_1.txt
-rw-r--r-- 1 shinokada staff 0 Jan 12 2011 file_2.txt
-rw-r--r-- 1 shinokada staff 0 Jan 12 2011 file_3.txt
-rw-r--r-- 1 shinokada staff 0 Jan 12 2011 file_4.txt
-rw-r--r-- 1 shinokada staff 0 Jan 12 2011 file_5.txt
As you can see all file's dates created are 2011 Jan 12 0.
How can I create files with a different year?
# this is what I want
-rw-r--r-- 1 shinokada staff 0 Jan 12 2011 file_1.txt
-rw-r--r-- 1 shinokada staff 0 Jan 12 2012 file_2.txt
-rw-r--r-- 1 shinokada staff 0 Jan 12 2013 file_3.txt
-rw-r--r-- 1 shinokada staff 0 Jan 12 2014 file_4.txt
-rw-r--r-- 1 shinokada staff 0 Jan 12 2015 file_5.txt
What is the best way?
touch command allows you to enter one one timestamp using -t option.
A traditional for-loop would be better:
for i in {1..5}; do touch -t 201${i}01120000 file_$i.txt; done
Shortly, but keeping filenumbers and years as separated variables
I think this is more readable, but...
Care about timezone!
filenum=1
for year in {2011..2015};do
TZ=UTC touch -t ${year}12312345 file-$((filenum++))
done
Then if you look about this, using a different timezone:
(Note that created date was Dec 31, 23h45')
TZ=UTC-1 ls -ltr
-rw-r--r-- 1 user user 0 jan 1 2012 file-1
-rw-r--r-- 1 user user 0 jan 1 2013 file-2
-rw-r--r-- 1 user user 0 jan 1 2014 file-3
-rw-r--r-- 1 user user 0 jan 1 2015 file-4
-rw-r--r-- 1 user user 0 jan 1 2016 file-5
Could you please try following, I would go with following approach with a for loop. Where I am providing year, number of files which needed, output file's initial value and same time value for all output files so that we can manage it in for loop.
cat script.bash
year=2011
numberoffiles="10"
time="01120000"
outputfileInitials="file"
nameSequence="1"
for ((i = 1 ; i <= numberoffiles ; i++ ));
do
touch -t $year$time "${outputfileInitials}_$nameSequence.txt"
(( nameSequence = nameSequence + 1 ))
(( year = year + 1 ))
done

Clean ten days and older logs using Shell

[root#amp logs]# ls -l
total 0
-rw-r--r-- 1 root root 0 Nov 23 17:51 lb-quarzcenter.log
-rw-r--r-- 1 root root 0 Feb 27 17:26 lb-quarzcenter.log.2019-02-01
-rw-r--r-- 1 root root 0 Feb 27 17:26 lb-quarzcenter.log.2019-02-02
-rw-r--r-- 1 root root 0 Feb 27 17:26 lb-quarzcenter.log.2019-02-03
-rw-r--r-- 1 root root 0 Feb 27 17:26 lb-quarzcenter.log.2019-02-04
-rw-r--r-- 1 root root 0 Feb 27 17:26 lb-quarzcenter.log.2019-02-05
-rw-r--r-- 1 root root 0 Feb 27 17:26 lb-quarzcenter.log.2019-02-06
-rw-r--r-- 1 root root 0 Feb 27 17:26 lb-quarzcenter.log.2019-02-07
-rw-r--r-- 1 root root 0 Feb 27 17:26 lb-quarzcenter.log.2019-02-08
-rw-r--r-- 1 root root 0 Feb 27 17:26 lb-quarzcenter.log.2019-02-10
-rw-r--r-- 1 root root 0 Feb 27 17:26 lb-quarzcenter.log.2019-02-11
-rw-r--r-- 1 root root 0 Feb 27 17:26 lb-quarzcenter.log.2019-02-12
-rw-r--r-- 1 root root 0 Feb 27 17:26 lb-quarzcenter.log.2019-02-13
-rw-r--r-- 1 root root 0 Feb 27 17:26 lb-quarzcenter.log.2019-02-14
-rw-r--r-- 1 root root 0 Nov 23 17:51 lb-quarzcenter.log.2019-02-15
-rw-r--r-- 1 root root 0 Feb 27 17:26 lb-quarzcenter.log.2019-02-09
How do I match a string with year-month-date and delete 10 days ago file according to lb-quarzcenter.log.*?
now=$(date +%s) # express current time as seconds since 1970-01-01
(( ten_days_ago = now - 60*60*24*10 )) # subtract 864000 seconds (10 days) from that
date_minus_ten=$(date +%F --date="#$ten_days_ago") # express that number as a YYYY-MM-DD
for filename in lb-quartzcenter.log.* ; do # loop over all matching files
filedate="${filename/lb-quartzcenter.log./}" # remove the filename part before the timestamp
if [[ $filedate < $date_minus_ten ]] ; then # if filename remainder is lexicographically lower...
rm -f "$filename" # ... remove the file
fi
done

Extract lines with duplicate last field

Based on a list generated with the command
find '/patch' -name A* -exec ls -la {} \;
Get only a list with file names that appears more than once (duplicated), but I want display the full line not only the file name.
File name consider only the name of file not the full path.
Example
Based on this file:
-rw-r--r-- 1 root root 34K Jan 9 2014 /usr/share/dia/sheets/AADL.sheet
-rw-r--r-- 1 root root 952 Fev 14 07:07 /usr/share/postgresql/9.3/man/man7/ABORT.7.gz
-rw-r--r-- 1 root root 955 Jul 30 2014 /usr/share/postgresql/9.1/man/man7/ABORT.7.gz
-rw-r--r-- 1 root root 92K Abr 28 2014 /usr/share/gettext/ABOUT-NLS
-rw-r--r-- 1 root root 545 Dez 14 2013 /usr/share/dia/sheets/Automata.sheet
-rw-r--r-- 1 root root 6,7K Dez 21 2012 /usr/share/perl5/Mail/Address.pm
-rw-r--r-- 1 root root 709 Mar 3 09:03 /home/test/Address.pm
-rw-r--r-- 1 root root 709 Mar 3 11:13 /home/test/Automata.sheet
-rw-r--r-- 1 root root 520 Mar 3 11:15 /home/test/t2/Address.pm
I want get this result:
-rw-r--r-- 1 root root 952 Fev 14 07:07 /usr/share/postgresql/9.3/man/man7/ABORT.7.gz
-rw-r--r-- 1 root root 955 Jul 30 2014 /usr/share/postgresql/9.1/man/man7/ABORT.7.gz
-rw-r--r-- 1 root root 6,7K Dez 21 2012 /usr/share/perl5/Mail/Address.pm
-rw-r--r-- 1 root root 709 Mar 3 09:03 /home/test/Address.pm
-rw-r--r-- 1 root root 520 Mar 3 11:15 /home/test/t2/Address.pm
-rw-r--r-- 1 root root 545 Dez 14 2013 /usr/share/dia/sheets/Automata.sheet
-rw-r--r-- 1 root root 709 Mar 3 11:13 /home/test/Automata.sheet
Using this commands
awk -F. '{ n = split($0, a, "/"); print a[n] }' file |sort | uniq -d > filedups
I got
ABORT.7.gz
Address.pm
Automata.sheet
and after
grep -f filedups file
I get expected result.
My question:
Is there a direct way to do this in just one line using awk and/or other commands?
awk to the rescue!
starting with your initial file
$ awk '{n=split($NF,a,"/"); k=a[n]; c[k]++;
v[k]=k in v?v[k] ORS $0:$0}
END {for(k in c) if(c[k]>1) print v[k]}' file
-rw-r--r-- 1 root root 6,7K Dez 21 2012 /usr/share/perl5/Mail/Address.pm
-rw-r--r-- 1 root root 709 Mar 3 09:03 /home/test/Address.pm
-rw-r--r-- 1 root root 520 Mar 3 11:15 /home/test/t2/Address.pm
-rw-r--r-- 1 root root 545 Dez 14 2013 /usr/share/dia/sheets/Automata.sheet
-rw-r--r-- 1 root root 709 Mar 3 11:13 /home/test/Automata.sheet
-rw-r--r-- 1 root root 952 Fev 14 07:07 /usr/share/postgresql/9.3/man/man7/ABORT.7.gz
-rw-r--r-- 1 root root 955 Jul 30 2014 /usr/share/postgresql/9.1/man/man7/ABORT.7.gz

how to print 3 lines in 1 column?

I've a file like below.
ab13p29im-sss29511
0
Jan 12 22:43
ab13p29im-sss29531
0
Jan 12 22:43
ab13p29im-sss29512
0
Feb 2 16:11
ab13p29im-sss29522
0
Feb 2 16:12
ab13p29im-sss29532
0
Feb 2 16:12
ab21p30im-sss30511
0
Jan 12 22:43
ab21p30im-sss30531
0
Jan 12 22:43
ab21p30im-sss30512
0
Feb 2 16:13
ab21p30im-sss30522
3
Feb 2 16:12
i want to print this is below format.
ab13p29im-sss29511 0 Jan 12 22:43
ab21p30im-sss30522 0 Feb 2 16:12
ab21p30im-sss30531 0 Jan 12 22:43
I'm using the command paste - - - < inputfile.But if any of the value is null, the format is all messed up like below?
ab13p29im-sss29511 0 Jan 12 22:43
ab21p30im-sss30522 0 ab21p30im-sss30531
0 Jan 12 22:43 ab21p30im-sss30523.
Like if there's no date for any host or if any value is null, it breaks the 3,3,3 pattern.
You like some like this:
awk 'ORS=NR%3?" ":RS' file
ab13p29im-sss29511 0 Jan 12 22:43
ab13p29im-sss29531 0 Jan 12 22:43
ab13p29im-sss29512 0 Feb 2 16:11
ab13p29im-sss29522 0 Feb 2 16:12
ab13p29im-sss29532 0 Feb 2 16:12
ab21p30im-sss30511 0 Jan 12 22:43
ab21p30im-sss30531 0 Jan 12 22:43
ab21p30im-sss30512 0 Feb 2 16:13
ab21p30im-sss30522 3 Feb 2 16:12
sed 'N;N;s/\n/ /g' YourFile
Load 2 lines, remove new line before printing it then cycle
you could secude by putting a pattern check to initiate the cycle like /[a-b0-9]\{9\}-[a-b0-9]\{8\}/!d; before first N
By using awk command and explicit concatenation:
$ awk 'NR % 3 == 1 { lines=$0 ; next } { lines=lines" "$0 } NR % 3 == 0 { print lines ; lines="" }' file
ab13p29im-sss29511 0 Jan 12 22:43
ab13p29im-sss29531 0 Jan 12 22:43
ab13p29im-sss29512 0 Feb 2 16:11
ab13p29im-sss29522 0 Feb 2 16:12
ab13p29im-sss29532 0 Feb 2 16:12
ab21p30im-sss30511 0 Jan 12 22:43
ab21p30im-sss30531 0 Jan 12 22:43
ab21p30im-sss30512 0 Feb 2 16:13
ab21p30im-sss30522 3 Feb 2 16:12

Resources