如何将递归找到的最新修改C++文件传递给g++编译?
解决方法:将最新修改的C文件传递给g编译
嘿,我懂你碰到的问题了——你已经能定位到最新修改的.cpp文件,但直接管道给g时出现了「no input files」错误,这是因为你的find命令输出的是包含时间戳、可读时间和文件名的整行内容,而g需要的是纯粹的文件名作为命令行参数,不是从标准输入读取文本内容。
咱们来一步步解决这个问题,提供几种可靠的方案:
方案一:用命令提取文件名并编译(简单易读)
先把最新文件的路径提取出来存到变量里,再传给g++,同时考虑文件名含空格的情况:
# 提取最新修改的.cpp文件路径 latest_cpp=$(find . -name '*.cpp' -type f -exec stat --format '%Y %n' {} + | sort -nr | head -n 1 | awk '{$1=""; print substr($0, 2)}') # 检查文件存在后编译 if [ -n "$latest_cpp" ]; then g++ "$latest_cpp" else echo "Error: 没有找到任何C++文件" fi
解释一下各部分的作用:
stat --format '%Y %n':只输出时间戳数字和文件名,比原来的格式更容易提取文件名sort -nr:按时间戳逆序排序,最新的文件排在最前面awk '{$1=""; print substr($0, 2)}':去掉第一个字段(时间戳),并删除开头的空格,得到完整的文件名(即使文件名含空格也能正确提取)- 用双引号包裹
$latest_cpp:避免文件名含空格时被g++拆成多个参数
方案二:全管道处理(更安全,适合复杂文件名)
如果你的环境中可能存在带空格、特殊字符的文件名,推荐用空字符分隔的方式处理,避免解析错误:
find . -name '*.cpp' -type f -printf '%T@ %p\0' | sort -z -nr | head -z -n 1 | awk -v RS='\0' '{sub(/^[0-9.]+ /, ""); print}' | xargs -0 g++
各部分细节:
find -printf '%T@ %p\0':%T@输出精确到小数的修改时间戳,%p是文件路径,\0用空字符分隔每个结果(完全避免空格/特殊字符问题)sort -z -nr、head -z -n1:分别按空字符分隔进行排序和取首行awk -v RS='\0':以空字符作为记录分隔符,精准提取每个文件条目,去掉开头的时间戳部分xargs -0:把空字符分隔的文件名传给g++,确保文件名被正确识别
为什么原来的命令会报错?
你原来的命令输出是类似1690000000 :2023-07-23 10:00:00 ./src/test.cpp的整行文本,当你把这个管道给g时,g会把这段文本当作待编译的代码内容(而不是文件名),但它找不到对应的输入文件,所以抛出「no input files」错误——g++默认只接受命令行参数里的文件名,不会主动从标准输入读取文件名哦。
内容的提问来源于stack exchange,提问作者Rami Chasygov
相关产品推荐
相关产品推荐

