簡體   English   中英

根據另一個文件中的數字從文件夾中的文本文件中提取行

[英]Extracting lines from text files in a folder based on the numbers in another file

我有一個文件ff.txt,如下所示

*ABNA.txt
 356
 24
 36
 112
*AC24.txt
 457
 458
 321
 2

ABNA.txt和AC24.txt是名為foo1的文件夾中的文件。 根據ff.txt文件中的數字,我想從foo1文件夾中的相應文件中提取行,並使用另一個文件夾foo2中的現有文件名創建新文件。 如果ABNA.txt文件的第三列或第四列包含356,24,36,112個數字,請提取該行並將其另存為另一個文件夾foo2,如ABNA.txt。

文件夾foo1中的ABNA.txt文件如下所示

dfg qza 356 245
hjb hkg 455 24
ghf qza 12  123
dfg qza 36  55

文件夾foo1中的AC24.txt文件如下所示

hjb hkg 457 167
ghf qza  2  165
sar sar 234 321
dfg qza 345 345

輸出:

文件夾foo2中的ABNA.txt文件

dfg qza 356 245
hjb hkg 455 24
dfg qza 36  55

文件夾foo2中的AC24.txt文件

hjb hkg 457 167
ghf qza  2  165
sar sar 234 321

你的幫助將不勝感激!

更新

這是一個純粹的bash解決方案( grep被刪除):

#!/bin/bash

file=
s=()

grp() { r="${s[@]}";r="\b("${r// /|}")\b";
  while read w; do [[ $w =~ $r ]] && echo $w;done <foo1/$file >foo2/$file
}

while read a; do
  if [[ $a =~ ^\* ]]; then
     [ -n "$file" ] && grp
     file=${a#\*}
     s=()
  else s=(${s[@]} $a)
  fi
done < ff.txt
[ -n "$file" ] && grp

#See input and output files
for i in foo1/*;{ echo %% in $i; cat $i;}
for i in foo2/*;{ echo %% out $i; cat $i;}

產量

%% in foo1/ABNA.txt
dfg qza 356 245
hjb hkg 455 24
ghf qza 12  123
dfg qza 36  55
%% in foo1/AC24.txt
hjb hkg 457 167
ghf qza  2  165
sar sar 234 321
dfg qza 345 345
%% out foo2/ABNA.txt
dfg qza 356 245
hjb hkg 455 24
dfg qza 36  55
%% out foo2/AC24.txt
hjb hkg 457 167
ghf qza  2  165
sar sar 234 321

在while循環中,它解析ff.txt文件。 如果一行以*開頭,則設置file環境變量。 如果不是以*開頭,則它是一個數字並添加到s數組中。 如果找到一個新的文件名並且有一個舊的文件名設置,那么它會調用grp函數來完成實際工作。

函數grp\\b(num1|num2...)\\b格式創建一個正則表達式。 \\b僅匹配完整的數字。 所以\\b24\\b245不匹配。 while循環從foo1讀取文件,將每一行與正則表達式匹配,並將具有相同名稱的文件寫入目錄foo2 它不檢查foo2目錄是否存在。

這可能適合你(GNU sed和Bash):

folder1=foo1
folder2=foo2
sed -r '/^\*/!{s/\s*//g;H;$!d};1{h;d};x;s/\n/ /;s/\n/|/g;s#\*(.*) (.*)#<'"$folder1"'/\1 sed -nr '\''/^(\\S+\\s+){2,3}\\b(\2)\\b/w '"$folder2"'/\1'\''#' ff.txt | sh

這會將ff.txt文件轉換為通過管道輸入sh命令的腳本。 用戶必須首先將bash變量$folder1$folder2到包含源文件和輸出文件的目錄中。

你可以試試這樣的東西 -

awk '
BEGIN {
    readpath=sprintf("%s", "/path/to/foo1")
    writepath=sprintf("%s", "/path/to/foo2")
    }
$0~/\*/ {
    file = substr($1,2)
    while ((getline var < (readpath"/"file)) > 0) {
        split (var, a, " ")
        ary[a[3]]=var
        ary[a[4]]=var
        }
    }
($1 in ary) {
    print ary[$1] > (writepath"/"file)
    }' foo.txt

闡釋:

  • BEGIN語句中設置讀取路徑和寫入路徑。
  • 對於在foo.txt文件中具有文件名的行
  • 使用substr捕獲名為file的變量中的文件名
  • 在名為var的變量中讀取文件。
  • 變量var 拆分為使用第3列和第4列作為數組ary的索引。
  • foo.txt文件中,如果數組中存在第一列作為索引,則將其寫入文件。

測試:

[jaypal:~/temp/test] ls
foo.txt foo1    foo2

[jaypal:~/temp/test] cat foo.txt
*ABNA.txt
356
24
36
112
*AC24.txt
457
458
321
2

[jaypal:~/temp/test] ls foo1/
ABNA.txt AC24.txt

[jaypal:~/temp/test] head foo1/*
==> foo1/ABNA.txt <==
dfg qza 356 245
hjb hkg 455 24
ghf qza 12  123
dfg qza 36  55

==> foo1/AC24.txt <==
hjb hkg 457 167
ghf qza  2  165
sar sar 234 321
dfg qza 345 345

[jaypal:~/temp/test] ls foo2/
[jaypal:~/temp/test] 

[jaypal:~/temp/test] awk '
BEGIN {
    readpath=sprintf("%s", "./foo1")
    writepath=sprintf("%s", "./foo2")
    }
$0~/\*/ {
    file = substr($1,2)
    while ((getline var < (readpath"/"file)) > 0) {
        split (var, a, " ")
        ary[a[3]]=var
        ary[a[4]]=var
        }
    }
($1 in ary) {
    print ary[$1] > (writepath"/"file)
    }' foo.txt

[jaypal:~/temp/test] ls foo2/
ABNA.txt AC24.txt

[jaypal:~/temp/test] head foo2/*
==> foo2/ABNA.txt <==
dfg qza 356 245
hjb hkg 455 24
dfg qza 36  55

==> foo2/AC24.txt <==
hjb hkg 457 167
sar sar 234 321
ghf qza  2  165
#!/bin/bash
mkdir -p foo2
awk '
    function process_file(filename, values,     filein, fileout, line, f) {
        if (filename == "") return
        filein = "./foo1/" filename
        fileout = "./foo2/" filename
        while ((getline line < filein) > 0) {
            split(line, f)
            if (f[3] in values || f[4] in values) {
                print line > fileout
            } 
        }
    }

    /^\*/ {
        process_file(filename, values)
        filename = substr($0, 2)
        delete values
        next
    }
    { values[$1] }
    END { process_file(filename, values) }
' ff.txt

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM