0

我在keywords.txt 文件中有一个关键字列表。我有另一个文件 list.txt,每行开头都有关键字。如何将 list.txt 中的行排序为它们在 keywords.txt 中出现的相同顺序?

关键字.txt

house
car
tree
woods
mailbox

列表.txt

car bbdfbdfbdfbdf
tree gdfgvsgsgs
mailbox gsgsdfsdf
woods gsgsdgsdgsdgsdgsddsd
house gsdgfsdgsdgsdgsdg

list.txt 中的最终结果

house gsdgfsdgsdgsdgsdg    
car bbdfbdfbdfbdf
tree gdfgvsgsgs
woods gsgsdgsdgsdgsdgsddsd
mailbox gsgsdfsdf
4

3 回答 3

1
$ join -1 2 -2 1 <(cat -n keywords.txt | sort -k2) <(sort list.txt) | sort -k2n | cut -d ' ' -f 1,3-
house gsdgfsdgsdgsdgsdg
car bbdfbdfbdfbdf
tree gdfgvsgsgs
woods gsgsdgsdgsdgsdgsddsd
mailbox gsgsdfsdf
于 2012-04-04T17:07:52.690 回答
1

这是kiswa答案的改进和简化版本。

@echo off
(
  for /f "usebackq" %%A in ("keywords.txt") do findstr /bl "%%A" list.txt
)>sorted.txt
REM move /y sorted.txt list.txt

FINDSTR 命令只匹配以关键字开头的行,并强制搜索为文字搜索。/L(如果未指定选项并且关键字恰好包含正则表达式元字符,则FINDSTR 可能会给出错误的结果。)

用排序后的文件替换原始文件的代码被注释掉了。只需删除 REM 语句即可激活 MOVE 语句。

与 kiswa 的回答一样,上面的内容只会输出 list.txt 中与keywords.txt 中的关键字匹配的行。

您可能在 list.txt 中有与关键字不匹配的行。如果要将这些行保留在排序输出的底部,请使用:

@echo off
(
  for /f "usebackq" %%A in ("keywords.txt") do findstr /bli "%%A" "list.txt"
  findstr /vblig:"keywords.txt" "list.txt"
)>sorted.txt
::move /y sorted.txt list.txt

请注意,/I必须使用(不区分大小写)选项,因为 FINDSTR 错误处理不同长度的多个文字搜索字符串。该/I选项避免了该错误,但如果您的关键字区分大小写,则会导致问题。请参阅Windows FINDSTR 命令有哪些未记录的功能和限制?.

您可能有 list.txt 中缺少的关键字。如果您想包含这些关键字而没有任何数据,请使用:

@echo off
(
  for /f "usebackq" %%A in ("keywords.txt") do findstr /bl "%%A" "list.txt" || echo %%A
)>sorted.txt
::move /y sorted.txt list.txt

显然,您可以结合这两种技术来确保保留两个文件的联合:

@echo off
(
  for /f "usebackq" %%A in ("keywords.txt") do findstr /bli "%%A" "list.txt" || echo %%A
  findstr /vblig:"keywords.txt" "list.txt"
)>sorted.txt
::move /y sorted.txt list.txt

以上所有假设关键字不包含空格或制表符。如果是这样,则 FOR /F 选项和 FINDSTR 选项必须更改:

@echo off
(
  for /f "usebackq delims=" %%A in ("keywords.txt") do findstr /bic:"%%A" "list.txt" || echo %%A
  findstr /vblig:"keywords.txt" "list.txt"
)>sorted.txt
::move /y sorted.txt list.txt
于 2012-04-04T18:59:09.513 回答
0

这是一个 Windows 批处理文件。它可能不是最有效的,但我认为它的可读性很好。

@echo off

for /F "tokens=*" %%A in (keywords.txt) do (
    for /F "tokens=*" %%B in ('findstr /i /C:"%%A" list.txt') do (
        echo %%B >> sorted.txt
    )
)

del list.txt

rename sorted.txt list.txt

这将创建一个排序文件,然后删除列表文件并重命名排序文件。

于 2012-04-04T17:47:22.217 回答