如何使用命令行将多个 URL 转换为域名

如何使用命令行将多个 URL 转换为域名

我有包含多列和“,”作为分隔符的 .csv 文件。网址位于第一列。我需要将所有网址转换为域而不删除其他列

我拥有的数据示例:

https://www.example.com/dog/url/path/cat.php,column2,$3,4
http://www.unix.random.com/index.html,column2,$3,4
http://example.com/dog/cat.php,column2,$3,4
www.example.com/dog/,column2,$3,4
example.com/url/path/cat/dog,column2,$3,4
https://example.com/,column2,$3,4
https://www.unix.random.com,column2,$3,4
http://www.example.com,column2,$3,4
http://example.com,column2,$3,4
www.random.com,column2,$3,4
example.com/,column2,$3,4 

我需要将第 1 列中的所有 url 转换为域名而不触及其他列,其他列不包含“/”。我需要保留 www 之外的子域。

输出需要是:

example.com,column2,$3,4
unix.random.com,column2,$3,4
example.com,column2,$3,4
example.com,column2,$3,4
example.com,column2,$3,4
example.com,column2,$3,4
unix.random.com,column2,$3,4
example.com,column2,$3,4
example.com,column2,$3,4
random.com,column2,$3,4
example.com,column2,$3,4 

这个怎么做?

答案1

使用任何 awk:

$ awk 'BEGIN{FS=OFS=","} {sub("^([^/:]+://)?(www[.])?","",$1); sub("/.*","",$1)} 1' file
example.com,column2,$3,4
unix.random.com,column2,$3,4
example.com,column2,$3,4
example.com,column2,$3,4
example.com,column2,$3,4
example.com,column2,$3,4
unix.random.com,column2,$3,4
example.com,column2,$3,4
example.com,column2,$3,4
random.com,column2,$3,4
example.com,column2,$3,4

答案2

我相信这有效:

sed -E 's#^(.*://)?(www\.)?##; s#^([^,/]+)[^,]*#\1#'

第一个 sed 命令 ( s#^(.*://)?(www\.)?##) 与协议和“www”相匹配。并用任何东西替换它。第二个 sed 命令 ( s#^([^,/]+)[^,]*#\1#) 匹配第一个斜杠之前的所有内容,然后匹配第一个逗号之前的所有内容,并将其替换为第一个斜杠之前的所有内容,因此它实际上删除了从第一个斜杠到第一个逗号之间的所有内容。

答案3

这可能不是您正在寻找的答案,但 sed 在不同操作系统之间可能不一致,并且其语法难以阅读。

这可能更糟,但另一种选择是在命令行上使用 Node.js 以及-e评估字符串的标志。这样做的缺点是您必须在系统上安装 Node.js。

此代码获取从标准输入通过管道传输到它的所有内容,并将修改后的字符串打印到标准输出:

cat infile.csv | node -e 'const stdin = process.openStdin();
let data = "";
stdin.on("data", chunk => data += chunk);
stdin.on("end", () => {
  console.log(
    data
      .trim()
      .split("\n")
      .filter(Boolean)
      .map((line) => {
        const parts = line.split(",");
        const url = new URL((!/^http(s)?\:\/\//.test(line) ? "https://" : "") + parts.shift());
        return `${url.host.replace(/^www\./,"")},${parts.join(",")}`
      })
      .join("\n"))
});' > outfile.csv

你可能有覆盖您的输入文件时遇到问题如果那是你想做的。为了解决这个问题,您可以在代码后面将文件名作为参数传递,而不是使用管道:

node -e 'const fs = require("fs");         
const infile = process.argv[1]; const data = fs.readFileSync(infile).toString();
const output = data
  .trim()
  .split("\n")
  .filter(Boolean)
  .map((line) => {
    const parts = line.split(",");
    const url = new URL((!/^http(s)?\:\/\//.test(line) ? "https://" : "") + parts.shift());
    return `${url.host.replace(/^www\./,"")},${parts.join(",")}`
  })
  .join("\n");
fs.writeFileSync(infile, output)' file.csv

答案4

使用(以前称为 Perl_6)

raku -pe 's{ (^ <-[/]>* \/\/ )? (w**3 \.)? (<-[/]>*) <-[,]>* } = "$2";'  

[以上是@HatLess 代码的翻译sed]。

raku -pe 's{ ^ (.* "://" )? (www\.)? } = ""; s{ ^ (<-[,/]>+) <-[,]>* } = "$0";' 

sed[以上是@D_Bear 代码的翻译]。

示例输出(两种情况):

example.com,column2,$3,4
unix.random.com,column2,$3,4
example.com,column2,$3,4
example.com,column2,$3,4
example.com,column2,$3,4
example.com,column2,$3,4
unix.random.com,column2,$3,4
example.com,column2,$3,4
example.com,column2,$3,4
random.com,column2,$3,4
example.com,column2,$3,4 

https://raku.org

相关内容