Home > other >  How to reformat the contents of a text file?
How to reformat the contents of a text file?

Time:12-13

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/

See: Input file

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:

Output file

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
  • Related