Use folder name as a column in a text file

Lazy me thinking about adding a column to some text files.

Text files are in directories, and I would like to add a directory name to a text file.

Like a text file text.txtin a folder the_peasant:

has a wart    
was dressed up like a witch     
has a false nose

will become:

the_peasant has a wart    
the_peasant was dressed up like a witch    
the_peasant has a false nose

Then I have similar text files in other folders called "the_king" etc.

I would think that this is a combination of the find, bash scripting and sed command, but I cannot view it. Any ideas?

+5
source share
9 answers

Directory Tree:

% tree .
.
├── the_king
│   └── text.txt
├── the_knight
│   └── text.txt
├── the_peasant
│   └── text.txt
└── wart.py
3 directories, 4 files

Directories and contents up to:

% find . -name 'text.txt' -print -exec cat {} \;       
./the_king/text.txt
has a wart    
was dressed up like a witch     
has a false nose
./the_knight/text.txt
has a wart    
was dressed up like a witch     
has a false nose
./the_peasant/text.txt
has a wart    
was dressed up like a witch     
has a false nose

Code (wart.py):

#!/usr/bin/env python

import os

text_file = 'text.txt'
cwd = os.path.curdir # '.'

# Walk thru each directory starting at '.' and if the directory contains
# 'text.txt', print each line of the file prefixed by the name containing
# directory.
for root, dirs, files in os.walk(cwd):
    if text_file in files: # We only care IF the file is in this directory.
        print 'Found %s!' % root
        filepath = os.path.join(root, text_file) # './the_peasant/text.txt'
        root_base = os.path.basename(root)       # './the_peasant' => 'the_peasant'
        output = ''
        with open(filepath, 'r') as reader:      # Open file for read/write
            for line in reader:                  # Iterate the lines of the file
                new_line = "%s %s" % (root_base, line)
                print new_line,
                output += new_line               # Append to the output

        with open(filepath, 'w') as writer:
            writer.write(output)                 # Write to the file

        print

What outputs:

Found ./the_king!
the_king has a wart    
the_king was dressed up like a witch     
the_king has a false nose

Found ./the_knight!
the_knight has a wart    
the_knight was dressed up like a witch     
the_knight has a false nose

Found ./the_peasant!
the_peasant has a wart    
the_peasant was dressed up like a witch     
the_peasant has a false nose

Directories and contents after:

% find . -name 'text.txt' -print -exec cat {} \;
./the_king/text.txt
the_king has a wart    
the_king was dressed up like a witch     
the_king has a false nose
./the_knight/text.txt
the_knight has a wart    
the_knight was dressed up like a witch     
the_knight has a false nose
./the_peasant/text.txt
the_peasant has a wart    
the_peasant was dressed up like a witch     
the_peasant has a false nose

It was fun! Thanks for the call!

+1
source

This might work for you:

find . -name text.txt | sed 's|.*/\(.*\)/.*|sed -i "s@^@\1 @" & |' | sh

GNU sed:

find . -name text.txt | sed 's|.*/\(.*\)/.*|sed -i "s@^@\1 @" & |e' 
+3

python script ( , , ):

#!/usr/bin/python
if __name__ == '__main__':
    import sys
    import os

    # Get full filepath and directory name
    filename = os.path.abspath(sys.argv[1])
    dirname = os.path.split(os.path.dirname(filename))[1]

    # Read current file contents
    my_file = open(filename, 'r')
    lines = my_file.readlines()
    my_file.close()

    # Rewrite lines, adding folder name to the start
    output_lines = [dirname + ' ' + line for line in lines]
    my_file = open(filename, 'w')
    my_file.write('\n'.join(output_lines))
    my_file.close()
+1

:

find /path/to/dir -type f | sed -r 'p;s:.*/(.*)/.*:\1:' | xargs -n 2 sh -c 'sed -i "s/^/$1 /" $0'

, , :

/home/the_peasant/a.txt
/home/the_peasant/b.txt
/home/the_peasant/farmer/c.txt

find /home/the_peasant -type f , .

sed , , :

/home/the_peasant/a.txt
the_peasant
/home/the_peasant/b.txt
the_peasant
/home/the_peasant/farmer/c.txt
farmer

xargs sh, :

$ sh -c 'sed -i "s/^/$1 /" $0' /home/the_peasant/a.txt the_peasant
$ sh -c 'sed -i "s/^/$1 /" $0' /home/the_peasant/b.txt the_peasant
$ sh -c 'sed -i "s/^/$1 /" $0' /home/the_peasant/farmer/c.txt farmer

, , sed, :

$ sed -i "s/^/the_peasant /" /home/the_peasant/a.txt
$ sed -i "s/^/the_peasant /" /home/the_peasant/b.txt
$ sed -i "s/^/farmer /" /home/the_peasant/farmer/c.txt
+1

find perl

find . -maxdepth 1 -mindepth 1 -type d | perl -MFile::Basename -ne 'chomp; my $dir = basename($_); for my $file (glob "$dir/*") { print qq{sed -i "s/^/$dir /" $file\n} }' | tee rename_commands.sh

sh rename_commands.sh

, perl sed $PATH. sed , , .

:

sed -i "s/^/foo /" foo/text1
sed -i "s/^/foo /" foo/text2
sed -i "s/^/bar /" bar/belvedere
sed -i "s/^/bar /" bar/robin
+1

.

  • , , fpath = "example.txt"
  • , dir_name , .

import os
fpath = "example.txt"
dir_name = os.path.dirname(fpath)
0

script ? os . , , os.path, :

import os, os.path

curDirectory = os.getcwd()
baseDir = os.path.basename()

inFile = open("filename.txt").xreadlines()
outFile = open("filename.out", "w")

for line in inFile:
    outFile.write("%s %s" % (baseDir, line))
outFile.close()
0

: , - . - . .

os.walk

import os.path
directory = os.path.curdir
pattern = ".py";
for (path,dirs,files) in os.walk(directory):
    for file in files:
        if not file.endswith(pattern):
            continue
        filename = os.path.join(path,file)
        #print "file: ",filename
        #continue
        with open(filename,"r") as f:
            for line in f.readlines():
                print "{0} {1}".format(filename,line)
            f.close()

:

list1.py   # LAB(replace solution)
list1.py   # return
list1.py   # LAB(end solution)
0

-ish-liner bash awk:

find . -type f -print0 |
while read -r -d "" path; do
  mv "$path" "$path.bak"
  awk -v dir="$(basename "$(dirname "$path")")" '{print dir, $0}' "$path.bak" > "$path"
done
0

All Articles