merge file text with file name

cat
8,420

Solution 1

That's quite trivial with awk:

$ awk '{print $0,FILENAME}' File*.txt
Apple File1.txt
Orange File1.txt
Banana File1.txt
monday File2.txt
tuesday File2.txt
wednesday File2.txt

If you want a tab rather than a space between the input line and the filename, add -v OFS='\t' to the command-line to set the Output Field Separator (OFS):

awk -v OFS='\t' '{print $0,FILENAME}' File*.txt

or use:

awk '{print $0 "\t" FILENAME}' File*.txt

That's assuming file names don't contain = characters. If you can't guarantee that the filenames won't contain = characters, you can change that to:

awk '{print $0 "\t" substr(FILENAME, 3)}' ./File*.txt

Though with GNU awk at least, you'd then get warnings if the name of the file contained bytes not forming valid characters (which you could work around by fixing the locale to C (with LC_ALL=C awk...) though that would also have the side effect of potentially changing the language of other error messages if any).

Solution 2

With perl:

perl -lpe '$_ .= "\t$ARGV"' File*.txt

(note that it's fine with a glob like File*.txt but could be dangerous with different ones).

Solution 3

For interactive use on the command line, one of the easiest things to type is

grep . File*.txt

Since the regex . matches any character, every non-empty line of every file will match, and be printed with the filename as a prefix.

It's great for use-cases like checking some kernel settings that are stored with one setting per file:

$ grep . /sys/kernel/mm/transparent_hugepage/*
/sys/kernel/mm/transparent_hugepage/defrag:[always] defer defer+madvise madvise never
/sys/kernel/mm/transparent_hugepage/enabled:[always] madvise never
/sys/kernel/mm/transparent_hugepage/hpage_pmd_size:2097152
grep: /sys/kernel/mm/transparent_hugepage/khugepaged: Is a directory
/sys/kernel/mm/transparent_hugepage/shmem_enabled:always [within_size] advise never deny force
/sys/kernel/mm/transparent_hugepage/use_zero_page:1
Share:
8,420

Related videos on Youtube

user247444
Author by

user247444

Updated on September 18, 2022

Comments

  • user247444
    user247444 almost 2 years

    I have two text files. The first "file1.txt" has content:

    Apple
    Orange
    Banana
    

    while the second file "file2.txt" has content:

    monday
    tuesday
    wednesday
    

    I want to combine them into one file and its output is:

    Apple       File1.txt
    Orange      File1.txt
    Banana      File1.txt
    monday      File2.txt
    tuesday     File2.txt
    wednesday   File2.txt
    
  • Alessio
    Alessio almost 7 years
    it's kind of annoying that gawk doesn't understand -- as most other GNU programs do or have some other way of stopping it from interpreting = in a filename asvar=value.
  • Stéphane Chazelas
    Stéphane Chazelas almost 7 years
    See grep -H . File*.txt with GNU grep or grep . /dev/null File*.txt with other finds if the glob may expand to only one file (and grep '^' File*.txt to print empty lines as well).
  • Stéphane Chazelas
    Stéphane Chazelas almost 7 years
    gawk does understand -- as end-of-options like all POSIX awk implementations (awk -- 'code' args) but it doesn't stop arguments with = from being treated as variable assignments. It has awk -E file.awk args for that though (so you can do gawk -e 'code' -E /dev/null other args x=y.txt File*.txt...). But that's gawk-specific.