英文:
Copy the file in second column when the first column match
问题
我想将文本文件第二列中列出的文件复制到目录dir1
,如果第一列是"include"或"Include"。我的脚本只会打印出所有行而不会复制文件。
main_file
这里是行
另一行
Include 'file1'
include 'file2'
文件结束
期望的输出
文件1和文件2已复制到dir1目录
我的脚本
awk 'tolower($1)=="include"{cp $2 dir1}' main_file
英文:
I would like to copy the files listed in the 2nd column of a text file to directory dir1
, if the 1st column is "include" or "Include". my script just prints out all lines without copying the files.
main_file
lines here
another line
Include 'file1'
include 'file2'
endoffile
desired output
file1 & file2 copied in the dir1 directory
my script
awk 'tolower($1)=="include"{cp $2 dir1}' main_file
答案1
得分: 2
执行操作系统操作(例如 cp
)在 awk
中,您需要查看 system()
函数,例如:
由于这里的目标是执行操作系统级文件复制,可能更直接的方法是在 bash
中执行此操作...
添加一个文件名中包含空格的文件并创建文件/目录:
$ cat main_file
lines here
another line
Include 'file1'
include 'file2'
include 'file3 with spaces'
endoffile
$ touch file1 file2 'file3 with spaces'
$ mkdir dir1
一个思路是:
while IFS="'" read -r _ fname _
do
cp "$fname" dir1
done < <(grep -i '^include ' main_file)
在运行任何一组代码(awk
,bash
)之前:
$ ls -l dir1
# 没有输出 => 目录中没有任何内容
在运行任何一组代码(awk
,bash
)之后:
$ ls -l dir1
-rw-rw----+ 1 用户名 用户组 30 6月 29 10:50 file1
-rw-rw----+ 1 用户名 用户组 90 6月 29 10:50 file2
-rw-rw----+ 1 用户名 用户组 0 6月 29 10:50 'file3 with spaces'
注意: 这两个解决方案(awk
,bash
)都假设文件名始终用单引号括起来,并且文件名不包含任何单引号。
英文:
To perform an OS operation (eg, cp
) from within awk
you'll want to look at the system()
function, eg:
awk -F"'" 'tolower($1) ~ /^include / {system("cp \"" $2 "\" dir1")}' main_file
Since the objective here is to perform an OS-level file copy it may be more straightforward to do this in bash
...
Adding a file with spaces in the name and creating the files/dir:
$ cat main_file
lines here
another line
Include 'file1'
include 'file2'
include 'file3 with spaces'
endoffile
$ touch file1 file2 'file3 with spaces'
$ mkdir dir1
One idea:
while IFS="'" read -r _ fname _
do
cp "$fname" dir1
done < <(grep -i '^include ' main_file)
Before running either set of code (awk
, bash
):
$ ls -l dir1
# no output => nothing in directory
After running either set of code (awk
, bash
):
$ ls -l dir1
-rw-rw----+ 1 username None 30 Jun 29 10:50 file1
-rw-rw----+ 1 username None 90 Jun 29 10:50 file2
-rw-rw----+ 1 username None 0 Jun 29 10:50 'file3 with spaces'
NOTE: both solutions (awk
, bash
) assume the file names are always wrapped in single quotes and the file names do not include any single quotes
答案2
得分: 1
I want to explain what your code
is actually doing:
tolower($1)=="include"
does a case-insensitive comparison, checking if the 1st column is "include" in any case. It includes variations like "Include," "INCLUDE," and so on.
{cp $2 dir1}
does string concatenation. If cp
and dir1
are undefined, GNU AWK
assumes they are empty strings. Since you didn't specify what to do with this concatenation, nothing is printed.
As far as I know, GNU AWK
doesn't have a built-in function for copying files. However, you can use GNU AWK
to prepare instructions for bash
like this:
Please note that this solution may have limitations and could break if dir1
doesn't exist or if there are single quotes within the file names. Consider using a programming language with better file handling features if possible.
英文:
I want to explain what your code
awk 'tolower($1)=="include"{cp $2 dir1}' main_file
is actually doing
tolower($1)=="include"
does case-insensitive comparison, this bit more sensitive that 1st column is "include" or "Include". (which would be expressed as $1=="include"||$1=="Include"
) as it also holds for INCLUDE, InClUdE and so on, but if these do not appear or should be treated same way will be ok.
{cp $2 dir1}
does string concatenation, as cp
and dir1
were not defined, GNU AWK
assumes that they are empty strings. As you did not instruct GNU AWK
what to do with effect of concatenation nothing is printed (at least in GNU Awk 5.1.0, which I used for testing).
As far as I know GNU AWK
has not function for copying files, however you might use GNU AWK
to prepare set of instructions for bash
following way
awk 'tolower($1)=="include"{print "cp " $2 " dir1"}' main_file | bash
Keep in mind that such solution is prone to breakage, as it did not care about dir1 existence and might malfunction if there is '
inside name of file, so if possible consider using language which sports features for dealing with copying files.
答案3
得分: 1
$ cat main_file
lines here
another line
包括 'file1'
包括 'file2'
包括 'file3 with spaces'
endoffile
$ grep -i "^include " main_file | xargs -n2 sh -c '[ -f "$1" ] && cp "$1" dir1/'
$ ls dir1
file1 file2 'file3 with spaces'
英文:
$ cat main_file
lines here
another line
Include 'file1'
include 'file2'
include 'file3 with spaces'
endoffile
$ grep -i "^include " main_file | xargs -n2 sh -c '[ -f "$1" ] && cp "$1" dir1/'
$ ls dir1
file1 file2 'file3 with spaces'
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论