move_lines.sh originally looked like this:
mv /home/user/filename.txt /home/user/filename.txt.old
mv /home/user/filename1.txt /home/user/filename1.txt.old
Code used so far:
awk '{print $1,$3}' move_lines.sh >> move_lines.sh
cd /home/user/oldfiles
currentdir=$(pwd)
echo "$currentdir" >> move_lines.sh
echo "$currentdir" >> move_lines.sh
unset $currentdir
Current output:
mv /home/user/filename.txt /home/user/filename.txt.old
mv /home/user/filename1.txt /home/user/filename1.txt.old
mv /home/user/filename1.txt.old
mv /home/user/filename1.txt.old
/home/user/oldfiles/
/home/user/oldfiles/
The goal is to make it look like this:
mv /home/user/filename.txt /home/user/filename.txt.old
mv /home/user/filename1.txt /home/user/filename1.txt.old
mv /home/user/filename1.txt.old /home/user/oldfiles/
mv /home/user/filename1.txt.old /home/user/oldfiles/
Unsure how to accomplish this. Any help would be greatly appreciated.
CodePudding user response:
I assume that your filenames do not contain spaces and that no more complete lines follow in the file finally.
awk 'NF==3; # print row with three columns
NF==2{ a2[ x]=$0 } # save row with two columns to array a2
NF==1{ a1[ y]=$0 } # save row with one columns to array a1
END{
for(i=1; i<=x; i )
print a2[i],a1[i] # print elements from both arrays
}' file
In one line:
awk 'NF==3; NF==2{ a2[ x]=$0 } NF==1{ a1[ y]=$0 } END{ for(i=1; i<=x; i ) print a2[i],a1[i] }' file
Output:
mv /home/user/filename.txt /home/user/filename.txt.old mv /home/user/filename1.txt /home/user/filename1.txt.old mv /home/user/filename1.txt.old /home/user/oldfiles/ mv /home/user/filename1.txt.old /home/user/oldfiles/
Assuming that:
- Line 5 should go behind line 3
- Line 6 should go behind line 4,
here's the code you can write
import os
input_file = 'input.txt'
output_file = 'output.txt'
default_path = '/home/user/oldfiles/'
# remove the output file
if os.path.exists(output_file):
os.remove(output_file)
# read all lines from input file
with open(input_file, 'r') as infile:
input_lines = infile.readlines()
# let's store good lines in output_lines and
# lines with missing last argument in orphaned_files
output_lines = []
orphaned_lines = []
# loop through all the read lines
for line in input_lines:
# remove empty spaces and new line characters at the end of the line
line = line.strip()
print('Reading line ', line)
# split by space and count # of arguments
arguments = line.split(' ')
print('Arguments count is ', len(arguments))
# this is the ideal line. Copy it to output_lines
if len(arguments) > 2:
print('Adding it to output_lines')
output_lines.append(line)
# this line is missing the last argument. Hold it in orphaned_lines
if len(arguments) == 2:
print('Found orphaned')
orphaned_lines.append(line)
# we found just the path. Add that to the first orphaned_line
# then, take that new line and put it in output_lines
if len(arguments) == 1:
# if there are any orphaned lines left, add this path
# to the first orphaned line
if len(orphaned_lines) > 0:
print('Adding it to the first orphaned')
orphaned_line = orphaned_lines.pop(0)
new_line = orphaned_line ' ' line
output_lines.append(new_line)
# if there are any orphaned lines still left, let's give them
# the default path
for line in orphaned_lines:
new_line = line ' ' default_path
output_lines.append(new_line)
# write to an output file
with open(output_file, 'w') as outfile:
for line in output_lines:
outfile.write(line '\n')
print('Done')
How do you run this file?
- Save the code in a file called test.py
- Assuming your input file that contains imperfect lines is called input.txt
- From command line, type
python3 test.py
- You will get a file called output.txt that will look like this:
Easier option with AWK
On command line, type:
awk '{n=split($0,a); if(n==3) print $0; else if (n==2) print $0" /home/user/oldfiles/" }' input.txt > output.txt
In this one-liner, we ask awk
to:
- split the line (represented by $0). When we split the line, the number of items are returned to a variable called
n
- If awk finds 3 items, we print the line
- If awk finds 2 items, we print the line followed by a space and the default path you desire
- Otherwise, don't print anything.
The output will go into output.txt and will look the same as the 2nd screenshot above.
Update
Based on your code, you could just do this on your bash prompt.
awk '{n=split($0,a); if(n==3) print $0; else if (n==2) print $0" /home/user/oldfiles/" }' move_lines.sh > new_move_lines.sh